Repository: actions/toolkit
Pull request #98 (2019-08-29 02:37:04)

Core debug
This pull request adds helpers for `group` and `endgroup`.

- Adds `core.startGroup('name')` and `core.endGroup()` for simple commands
- Adds `core.group('name', asyncFn)` for wrapping asynchronous commands 


Patch:
diff --git a/packages/core/README.md b/packages/core/README.md
index 4520ce2..58a8287 100644
--- a/packages/core/README.md
+++ b/packages/core/README.md
@@ -78,3 +78,20 @@ catch (err) {
   core.error(`Error ${err}, action may still succeed though`);
 }
 ```
+
+This library can also wrap chunks of output in foldable groups.
+
+```js
+const core = require('@actions/core')
+
+// Manually wrap output
+core.startGroup('Do some function')
+doSomeFunction()
+core.endGroup()
+
+// Wrap an asynchronous function call
+const result = await core.group('Do something async', async () => {
+  const response = await doSomeHTTPRequest()
+  return response
+})
+```
\ No newline at end of file
diff --git a/packages/core/src/command.ts b/packages/core/src/command.ts
index c3cb705..4e6e9b4 100644
--- a/packages/core/src/command.ts
+++ b/packages/core/src/command.ts
@@ -25,7 +25,7 @@ export function issueCommand(
   process.stdout.write(cmd.toString() + os.EOL)
 }
 
-export function issue(name: string, message: string): void {
+export function issue(name: string, message: string = ''): void {
   issueCommand(name, {}, message)
 }
 
diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts
index 2fa992b..d98e4d7 100644
--- a/packages/core/src/core.ts
+++ b/packages/core/src/core.ts
@@ -130,3 +130,43 @@ export function error(message: string): void {
 export function warning(message: string): void {
   issue('warning', message)
 }
+
+/**
+ * Begin an output group.
+ *
+ * Output until the next `groupEnd` will be foldable in this group
+ *
+ * @param name The name of the output group
+ */
+export function startGroup(name: string): void {
+  issue('group', name)
+}
+
+/**
+ * End an output group.
+ */
+export function endGroup(): void {
+  issue('endgroup')
+}
+
+/**
+ * Wrap an asynchronous function call in a group.
+ *
+ * Returns the same type as the function itself.
+ *
+ * @param name The name of the group
+ * @param fn The function to wrap in the group
+ */
+export async function group<T>(name: string, fn: () => Promise<T>): Promise<T> {
+  startGroup(name)
+
+  let result: T
+
+  try {
+    result = await fn()
+  } finally {
+    endGroup()
+  }
+
+  return result
+}


Test patch:
diff --git a/packages/core/__tests__/lib.test.ts b/packages/core/__tests__/lib.test.ts
index 623d4aa..dc34213 100644
--- a/packages/core/__tests__/lib.test.ts
+++ b/packages/core/__tests__/lib.test.ts
@@ -155,6 +155,29 @@ describe('@actions/core', () => {
     assertWriteCalls([`##[warning]%0D%0Awarning%0A${os.EOL}`])
   })
 
+  it('startGroup starts a new group', () => {
+    core.startGroup('my-group')
+    assertWriteCalls([`##[group]my-group${os.EOL}`])
+  })
+
+  it('endGroup ends new group', () => {
+    core.endGroup()
+    assertWriteCalls([`##[endgroup]${os.EOL}`])
+  })
+
+  it('group wraps an async call in a group', async () => {
+    const result = await core.group('mygroup', async () => {
+      process.stdout.write('in my group\n')
+      return true
+    })
+    expect(result).toBe(true)
+    assertWriteCalls([
+      `##[group]mygroup${os.EOL}`,
+      'in my group\n',
+      `##[endgroup]${os.EOL}`
+    ])
+  })
+
   it('debug sets the correct message', () => {
     core.debug('Debug')
     assertWriteCalls([`##[debug]Debug${os.EOL}`])