Repository: actions/toolkit
Pull request #149 (2019-09-20 02:03:30)

add core method to saveState and getState.
In wrapper action, action author uses these 2 methods for sharing information between his action's main-execution and post-execution, this information is only available to this pair of action's executions, other action within the same job won't get it.

Ex: 
In the main execution:
```javascript
  core.saveState("pidToKill", 12345);
```
In the post-execution:
```javascript
  var pid = core.getState("pidToKill");
  process.kill(pid);
```


Patch:
diff --git a/packages/core/README.md b/packages/core/README.md
index 58a8287..d34b950 100644
--- a/packages/core/README.md
+++ b/packages/core/README.md
@@ -94,4 +94,37 @@ const result = await core.group('Do something async', async () => {
   const response = await doSomeHTTPRequest()
   return response
 })
+```
+
+#### Action state
+
+You can use this library to save state and get state for sharing information between a given wrapper action: 
+
+**action.yml**
+```yaml
+name: 'Wrapper action sample'
+inputs:
+  name:
+    default: 'GitHub'
+runs:
+  using: 'node12'
+  main: 'main.js'
+  post: 'cleanup.js'
+```
+
+In action's `main.js`:
+
+```js
+const core = require('@actions/core');
+
+core.saveState("pidToKill", 12345);
+```
+
+In action's `cleanup.js`:
+```js
+const core = require('@actions/core');
+
+var pid = core.getState("pidToKill");
+
+process.kill(pid);
 ```
\ No newline at end of file
diff --git a/packages/core/src/core.ts b/packages/core/src/core.ts
index 072f232..3fee6bb 100644
--- a/packages/core/src/core.ts
+++ b/packages/core/src/core.ts
@@ -178,3 +178,27 @@ export async function group<T>(name: string, fn: () => Promise<T>): Promise<T> {
 
   return result
 }
+
+//-----------------------------------------------------------------------
+// Wrapper action state
+//-----------------------------------------------------------------------
+
+/**
+ * Saves state for current action, the state can only be retrieved by this action's post job execution.
+ *
+ * @param     name     name of the state to store
+ * @param     value    value to store
+ */
+export function saveState(name: string, value: string): void {
+  issueCommand('save-state', {name}, value)
+}
+
+/**
+ * Gets the value of an state set by this action's main execution.
+ *
+ * @param     name     name of the state to get
+ * @returns   string
+ */
+export function getState(name: string): string {
+  return process.env[`STATE_${name}`] || ''
+}


Test patch:
diff --git a/packages/core/__tests__/lib.test.ts b/packages/core/__tests__/lib.test.ts
index 0bbe43d..364cfd1 100644
--- a/packages/core/__tests__/lib.test.ts
+++ b/packages/core/__tests__/lib.test.ts
@@ -17,7 +17,10 @@ const testEnvVars = {
   INPUT_MY_INPUT: 'val',
   INPUT_MISSING: '',
   'INPUT_SPECIAL_CHARS_\'\t"\\': '\'\t"\\ response ',
-  INPUT_MULTIPLE_SPACES_VARIABLE: 'I have multiple spaces'
+  INPUT_MULTIPLE_SPACES_VARIABLE: 'I have multiple spaces',
+
+  // Save inputs
+  STATE_TEST_1: 'state_val'
 }
 
 describe('@actions/core', () => {
@@ -194,6 +197,15 @@ describe('@actions/core', () => {
     core.debug('\r\ndebug\n')
     assertWriteCalls([`::debug::%0D%0Adebug%0A${os.EOL}`])
   })
+
+  it('saveState produces the correct command', () => {
+    core.saveState('state_1', 'some value')
+    assertWriteCalls([`::save-state name=state_1,::some value${os.EOL}`])
+  })
+
+  it('getState gets wrapper action state', () => {
+    expect(core.getState('TEST_1')).toBe('state_val')
+  })
 })
 
 // Assert that process.stdout.write calls called only with the given arguments.