Compare commits

...

58 Commits

Author SHA1 Message Date
Jonathan Clem a2ab4bcf78 Publish
Main workflow / Run macOS (push) Has been cancelled
Main workflow / Run Windows (push) Has been cancelled
Main workflow / Run Ubuntu (push) Has been cancelled
- @actions/core@1.1.0
 - @actions/exec@1.0.1
 - @actions/github@1.1.0
 - @actions/io@1.0.1
 - @actions/tool-cache@1.1.1
2019-09-05 11:03:19 -04:00
Jonathan Clem 7772d5f810 Merge pull request #113 from actions/client-options
Accept Octokit.Options in the GitHub constructor
2019-09-05 10:58:15 -04:00
Jonathan Clem 1c4866fa48 Add note about constructor options 2019-09-05 10:52:34 -04:00
Jonathan Clem ebace7edd3 Bump TypeScript to 3.6.2 2019-09-05 10:03:10 -04:00
Jonathan Clem e533651251 Accept Octokit.Options in the GitHub constructor 2019-09-05 09:54:27 -04:00
Jonathan Clem eb4c32847c Merge pull request #98 from actions/core-debug
Core debug
2019-09-05 09:47:05 -04:00
Bryan MacFarlane 020f7034f4 JavaScript walk through update (#107)
* update walkthrough

* review feedback
2019-09-04 17:30:45 -04:00
damccorm 2a1b7d5c7e Merge branch 'master' of https://github.com/actions/toolkit 2019-09-04 14:04:40 -04:00
damccorm eaba9217f8 Bump package version 2019-09-04 14:04:31 -04:00
Danny McCormick f2d01998f0 Update RELEASES.md 2019-09-03 14:42:04 -04:00
Danny McCormick 99d3ad0a64 Use readFileSync instead of require (#101)
* Use readFileSync instead of require

* error handling
2019-08-30 13:02:45 -04:00
Guillaume Clochard ac36ca4405 Small fix for the tool-cache extract example (#99)
* Fix tool-cache extract example

* Use extractZip or extract7z in tool-cache example fix
2019-08-29 11:08:06 -04:00
Jonathan Clem 92e6443cf0 End group in core.group regardless of error thrown 2019-08-28 22:47:37 -04:00
Jonathan Clem 8f9992ca17 Add assertion for return value of core.group 2019-08-28 22:38:30 -04:00
Jonathan Clem 80fc75ef9c Fix readme 2019-08-28 22:36:17 -04:00
Jonathan Clem 8b9dfa809b Add group functions to core 2019-08-28 22:35:27 -04:00
dependabot[bot] e35e0e640b Bump mixin-deep from 1.3.1 to 1.3.2 (#95)
Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/jonschlinkert/mixin-deep/releases)
- [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-28 09:45:33 -04:00
dependabot[bot] ccf748b53b Bump lodash.template from 4.4.0 to 4.5.0 (#94)
Bumps [lodash.template](https://github.com/lodash/lodash) from 4.4.0 to 4.5.0.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.4.0...4.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-28 09:35:15 -04:00
dependabot[bot] 8caeee5d56 Bump tar from 2.2.1 to 2.2.2 (#93)
Bumps [tar](https://github.com/npm/node-tar) from 2.2.1 to 2.2.2.
- [Release notes](https://github.com/npm/node-tar/releases)
- [Commits](https://github.com/npm/node-tar/compare/v2.2.1...v2.2.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-28 09:34:59 -04:00
dependabot[bot] b26ef29d75 Bump lodash from 4.17.11 to 4.17.15 (#92)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.11 to 4.17.15.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.11...4.17.15)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-28 09:34:46 -04:00
dependabot[bot] fba68de49e Bump fstream from 1.0.11 to 1.0.12 (#91)
Bumps [fstream](https://github.com/npm/fstream) from 1.0.11 to 1.0.12.
- [Release notes](https://github.com/npm/fstream/releases)
- [Commits](https://github.com/npm/fstream/compare/v1.0.11...v1.0.12)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-28 09:34:34 -04:00
dependabot[bot] df04d7dbaf Bump eslint-utils from 1.3.1 to 1.4.2 (#90)
Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/mysticatea/eslint-utils/releases)
- [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.3.1...v1.4.2)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-28 09:34:20 -04:00
AEnterprise 37202e8dbc fix syntax error in output example (#84) 2019-08-26 08:41:40 -04:00
Bryan MacFarlane 7cd421b8bc lint fixes 2019-08-25 00:55:22 -04:00
Bryan MacFarlane 17a0aa40f3 taking out some tests 2019-08-25 00:26:39 -04:00
Bryan MacFarlane b7ae833847 bit of branding 2019-08-24 09:24:48 -04:00
Bryan MacFarlane a2078cf37c raising not implemented earlier 2019-08-24 09:22:38 -04:00
Bryan MacFarlane 4ebc9007c0 removing not implemented function from docs 2019-08-24 09:17:35 -04:00
Bryan MacFarlane f66f5629b3 updating keywords 2019-08-23 17:39:40 -04:00
Sven-Hendrik Haase ac007c0698 Fix path (#78)
The current one seems like an uncommon Windows-like notation.
2019-08-23 10:42:51 -04:00
Danny McCormick 6b9630ac94 Add RELEASES.md for each package, bump tool-cache to publish (#67) 2019-08-22 13:14:49 -04:00
Akshay Iyyadurai Balasundaram e54c7a866d Fix: wrong spelling for using action in a workflow (#76) 2019-08-22 13:13:36 -04:00
Scott Brenner 750d949f10 container-action typo fix (#77) 2019-08-22 13:12:47 -04:00
Sven-Hendrik Haase 28803fc3b4 Correct wrong docs (#75)
Docs say it's `using:` but it's actually `uses:`.
2019-08-21 22:31:21 -04:00
Josh Soref ad054c855d Spelling (#72)
* spelling: check in

* spelling: compatibility

* spelling: definitely

* spelling: does not

* spelling: maintaining

* spelling: nonexistent

* spelling: precede

* spelling: response

* spelling: was not
2019-08-21 15:31:44 -04:00
Danny McCormick 7d605994f9 Comment nit 2019-08-21 12:54:24 -04:00
Jason Etcovitch e7914df1c6 Merge pull request #70 from actions/highlight-codeblocks
Highlight codeblocks in markdown files
2019-08-21 07:52:24 -07:00
Jason Etcovitch 1d687b2170 tool-cache/README.md 2019-08-21 01:18:31 -04:00
Jason Etcovitch a796c65f64 io/README.md 2019-08-21 01:18:21 -04:00
Jason Etcovitch 5e3e440c7f exec/README.md 2019-08-21 01:18:00 -04:00
Jason Etcovitch ea2ffbe002 Some more in the docs 2019-08-21 01:16:51 -04:00
Jason Etcovitch db9fd45770 Missed one 2019-08-21 01:16:47 -04:00
Jason Etcovitch 770cf14bde Highlight codeblocks in core/README.md 2019-08-20 22:15:05 -07:00
James M. Greene 00fc8b2580 Fix secrets reference syntax in README (#68) 2019-08-20 15:46:20 -04:00
Sören Wegener e2adf403d6 Typofix in markdown (#63) 2019-08-18 19:38:45 -04:00
Kenny Root 35ed15faaf Fix typo in README.md (#62)
Missed a "k" in "Walkthrough."
2019-08-18 19:28:10 -04:00
James M. Greene 9821b26794 Fix syntax mistake in README (#55) 2019-08-13 18:13:12 -04:00
Danny McCormick 8662b07822 Remove format step 2019-08-13 16:03:45 -04:00
Alif Rachmawadi 2c3e55b8c9 Add more supports for tar extensions (#48)
* added test for extracting .tar.gz

* added ability to extract .tar.xz

* add flags to extract tar

* make use of tempPath

* check file contents and make different content for tar file
2019-08-13 14:26:14 -04:00
Alif Rachmawadi 35cd59e8d5 Added unzip for darwin (#49)
* added unzip for darwin

* add mac builds

* added zip for darwin
2019-08-13 12:39:01 -04:00
Thomas Boop eae6c87114 Add Action Debugging information (#46)
* Add Action Debugging information

* Small verbiage updates

* Update README.md

* minor grammar updates
2019-08-12 17:00:55 -04:00
Danny McCormick 938549d01a Add status badge 2019-08-12 15:09:43 -04:00
Danny McCormick 079812ed8a Add github package to readme 2019-08-12 14:28:37 -04:00
Bryan MacFarlane ac5434c423 update some naming 2019-08-09 15:06:50 -04:00
Danny McCormick 4c46ecfd35 Add debug info 2019-08-09 13:55:59 -04:00
Sascha Wolf 534e4012a4 Docs: Fix link to the versioning file (#45)
The link to `action-versioning.md` was relative which lead to appending an additional `docs` folder to the current path which linked to `docs/docs/action-versioning.md` instead of `docs/action-versioning.md`.

By adding the leading `/` the link now works correctly.
2019-08-09 07:58:16 -04:00
Curtis Gibby 71fe4a8f36 Fix bad apostrophes (#44)
A possessive belonging to an "it" doesn't need an apostrophe. Don't believe me? Ask [the Oatmeal](http://theoatmeal.com/comics/apostrophe) (look for the velociraptor)!
2019-08-08 13:40:24 -04:00
Gregor Martynus aec0ef46e4 [@actions/github] Fix code example, add syntax highlighting (#43)
* [@actions/github] Fix code example, add syntax highlighting

* [@actions/github] add link to @octkit/graphql API

* [@octokit/github] moar syntax highlighting in README
2019-08-07 17:23:44 -04:00
44 changed files with 496 additions and 266 deletions
+23
View File
@@ -30,6 +30,29 @@ jobs:
- name: Format - name: Format
run: npm run format-check run: npm run format-check
macOS:
name: Run macOS
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Set Node.js 10.x
uses: actions/setup-node@master
with:
version: 10.x
- name: npm install
run: npm install
- name: Bootstrap
run: npm run bootstrap
- name: Compile
run: npm run build
- name: npm test
run: npm test
Windows: Windows:
name: Run Windows name: Run Windows
runs-on: windows-latest runs-on: windows-latest
+11 -6
View File
@@ -3,13 +3,17 @@
<img src="res/at-logo.png"> <img src="res/at-logo.png">
</p> </p>
## Toolkit <p align="center">
<a href="https://github.com/actions/toolkit"><img alt="GitHub Actions status" src="https://github.com/actions/toolkit/workflows/Main%20workflow/badge.svg"></a>
</p>
The toolkit provides a set of packages to make creating actions easier and drive consistency. ## GitHub Actions Toolkit
The GitHub Actions ToolKit provides a set of packages to make creating actions easier and drive consistency.
## Packages ## Packages
The toolkit provides four separate packages. Since actions are run by pulling actions from the github graph, dependencies including the packages are vendored into your action. The toolkit provides five separate packages. See the docs for each action.
| Package | Description | | Package | Description |
| ------- | ----------- | | ------- | ----------- |
@@ -17,14 +21,15 @@ The toolkit provides four separate packages. Since actions are run by pulling a
| [@actions/exec](packages/exec) | Functions necessary for running tools on the command line | | [@actions/exec](packages/exec) | Functions necessary for running tools on the command line |
| [@actions/io](packages/io) | Core functions for CLI filesystem scenarios | | [@actions/io](packages/io) | Core functions for CLI filesystem scenarios |
| [@actions/tool-cache](packages/tool-cache) | Functions necessary for downloading and caching tools | | [@actions/tool-cache](packages/tool-cache) | Functions necessary for downloading and caching tools |
| [@actions/github](packages/github) | An Octokit client hydrated with the context that the current action is being run in |
## Creating an Action with the Toolkit ## Creating an Action with the Toolkit
Actions are units of work which can either run in a container or on the host machine. Actions are units of work which can either run in a container or on the host machine.
[Choosing an action type](docs/action-types.md): Outlines the differences and why you would want to create a host or a container based action. [Choosing an action type](docs/action-types.md): Outlines the differences and why you would want to create a JavaScript or a container based action.
[JavaScript Action Walthrough](docs/node12-action.md): Create an action which runs on the host using the toolkit [JavaScript Action Walkthrough using a Template](docs/javascript-action.md): A full walkthrough creating an action using the toolkit along with TypeScript for compile time support and Jest for unit testing. It also covers a branching strategy for versioning and safely testing and releasing an action.
[Docker Action Walkthrough](docs/container-action.md): Create an action that is delivered as a container and run with docker. [Docker Action Walkthrough](docs/container-action.md): Create an action that is delivered as a container and run with docker.
@@ -34,4 +39,4 @@ Actions are units of work which can either run in a container or on the host mac
## Contributing ## Contributing
We welcome contributions. See [how to contribute](docs/contribute.md). We welcome contributions. See [how to contribute](docs/contribute.md).
+26
View File
@@ -0,0 +1,26 @@
# Debugging
If the build logs do not provide enough detail on why a build may be failing, some other options exist to assist with troubleshooting.
## Runner Diagnostic Logs
Runner Diagnostic Logs provide additional log files detailing how the Runner is executing an action.
Each file contains different logging information that corresponds to that process:
* The Runner process coordinates setting up workers to execute jobs.
* The Worker process executes the job.
These files contain the prefix `Runner_` or `Worker_` to indicate the log source.
### How to Access Runner Diagnostic Logs
These log files are enabled by [setting the secret](https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables) `ACTIONS_RUNNER_DEBUG` to `true`.
All actions ran while this secret is enabled contain additional diagnostic log files in the `runner-diagnostic-logs` folder of the [log archive](https://help.github.com/en/articles/managing-a-workflow-run#downloading-logs-and-artifacts).
## Step Debug Logs
Step debug logs increase the verbosity of a job's logs during and after a job's execution to assist with troubleshooting.
Additional log events with the prefix `##[debug]` will now also appear in the job's logs.
### How to Access Step Debug Logs
This flag can be enabled by [setting the secret](https://help.github.com/en/articles/virtual-environments-for-github-actions#creating-and-using-secrets-encrypted-variables) `ACTIONS_STEP_DEBUG` to `true`.
All actions ran while this secret is enabled will show debug events in the [Downloaded Logs](https://help.github.com/en/articles/managing-a-workflow-run#downloading-logs-and-artifacts) and [Web Logs](https://help.github.com/en/articles/managing-a-workflow-run#viewing-logs-to-diagnose-failures).
+4 -4
View File
@@ -3,7 +3,7 @@
There are two types of actions. JavaScript and Docker actions. There are two types of actions. JavaScript and Docker actions.
- **JavaScript Actions**: JavaScript actions run on the host machine. The unit of work is decoupled from the environment. - **JavaScript Actions**: JavaScript actions run on the host machine. The unit of work is decoupled from the environment.
- **Docker Actions**: A container action is a container which carries both the unit of work along with the environment and it's dependencies packaged up as a container. - **Docker Actions**: A container action is a container which carries both the unit of work along with the environment and its dependencies packaged up as a container.
Both have access to the workspace and the github event payload and context. Both have access to the workspace and the github event payload and context.
@@ -11,7 +11,7 @@ Both have access to the workspace and the github event payload and context.
Docker actions carry both the unit of work and the environment. Docker actions carry both the unit of work and the environment.
This creates a more consistent and reliable unit of work where the consumer of the action does not need to worry about the toolsets and it's dependencies. This creates a more consistent and reliable unit of work where the consumer of the action does not need to worry about the toolsets and its dependencies.
Docker actions are currently limited to Linux only. Docker actions are currently limited to Linux only.
@@ -19,7 +19,7 @@ Docker actions are currently limited to Linux only.
JavaScript actions decouple the unit of work from the environment and run directly on the host machine or VM. JavaScript actions decouple the unit of work from the environment and run directly on the host machine or VM.
Consider a simple example of testing a node lib on node 8, 10 and running a custom action. Each job will setup a node version on the host and custom-action will run it's unit of work on each environment (node8+ubunut16, node8+windows-2019, etc.) Consider a simple example of testing a node lib on node 8, 10 and running a custom action. Each job will setup a node version on the host and custom-action will run its unit of work on each environment (node8+ubuntu16, node8+windows-2019, etc.)
```yaml ```yaml
on: push on: push
@@ -42,4 +42,4 @@ jobs:
- uses: actions/custom-action@master - uses: actions/custom-action@master
``` ```
JavaScript actions work on any environment that host action runtime is supported on which is currently node 12. However, a host action that runs a toolset expects the environment that it's running on to have that toolset in it's PATH or using a setup-* action to acquire it on demand. JavaScript actions work on any environment that host action runtime is supported on which is currently node 12. However, a host action that runs a toolset expects the environment that it's running on to have that toolset in its PATH or using a setup-* action to acquire it on demand.
+8 -2
View File
@@ -13,9 +13,9 @@ steps:
Binding to the immutable sha1 of a released version is the safest for stability and security. Binding to the immutable sha1 of a released version is the safest for stability and security.
Binding to a specific major version allows for receiving critical fixes and security patches while still mainting compatibility and the assurance your workflow should still work. Binding to a specific major version allows for receiving critical fixes and security patches while still maintaining compatibility and the assurance your workflow should still work.
Binding to master is convenient but if a new major version is released which breaks compatilibility, your workflow could break. Binding to master is convenient but if a new major version is released which breaks compatibility, your workflow could break.
# Recommendations # Recommendations
@@ -41,3 +41,9 @@ git push origin v1
5. **Compatibility Breaks**: introduce a new major version branch (releases/v2) and tag (v2) if changes will break existing workflows. For example, changing inputs. 5. **Compatibility Breaks**: introduce a new major version branch (releases/v2) and tag (v2) if changes will break existing workflows. For example, changing inputs.
See [Git-Basics-Tagging](https://git-scm.com/book/en/v2/Git-Basics-Tagging) See [Git-Basics-Tagging](https://git-scm.com/book/en/v2/Git-Basics-Tagging)
# Sample Workflow
This illustrates one possible versioning workflow which the walk through covered.
![versioning](assets/action-releases.png)
+1
View File
@@ -0,0 +1 @@
<mxfile modified="2019-09-04T11:27:58.307Z" host="www.draw.io" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36" etag="MFzGVuAX-y50cwbudjLg" version="11.2.5" type="device" pages="1"><diagram name="Page-1" id="ff44883e-f642-bcb2-894b-16b3d25a3f0b">7Vtbc5s4GP01nj4lA+L+WCdp96E70910uu1TB4OMmWDkEdhx9tfvJ5AMSPIta4Mbx5mJ0R10zncVHll38/VnGi5mf5IYZyNkxOuRdT9CyHds+M8qXuoKxzPqioSmcV1lNhWP6b+YV4puyzTGRadjSUhWpotuZUTyHEdlpy6klDx3u01J1l11ESZYqXiMwkzU3jpN/T9pXM54vekGTcMfOE1mfHEfuXXDJIyeEkqWOV9xhKxp9amb56GYiz9qMQtj8tyqsh5G1h0lpKyv5us7nLHNFRsnxpUv4m5H1nhWzjMomHBZNX/aMtg8ZDA8HMV52V5u23xTYxJFQWAZNnanTngTKPPjGHaWF3OSw9c4WtIVjvmKrcWLMqQlJwMwwRrjPP7I0IRylIVFkUZ15ac0E2Og1B5RlJQ84TuSEVotbxnVZ9MisGSPPSX5ZjVUTVXSlx+beaHwEwoGUIEX7xm9jU3pRZTWafmjdd0aBaVmECuIMeo+C2TIkkZYv7mIS0JIE1zqu/BZ2Ka3puXYfcZkjuHOoQPFWVimq64QhFxqkk2/zdCvJIUbRQYXcFsIKpdvT8i3mKJ+DD6q4Q9ctG6jqapYdRjDTPfUFNvHpp2c0WG/E/kNy1rE+tkm3RaWvYox1n7GoH4YY0mM8WXG1Pd4FsbUC63CbMnvPlLVIEwBxoVR53mWlvhxEVZ7+gzmrcugSrVX1KoYIrS3qVM+bvVRiGR3iWSxicIsTXKm5wBeTFkHYGVrqqnD/nbxYIVpidc7MeStyO9isbHOz42lE11mbRtnbEe9g9cx4Kjm7NLEeY8qf63ZeJVAuxcj0E4gkcjqTaCRKtBoUIE2BxZo27scgbZUcKyrBseRwPHRcODYKjjOVYPjyVpsSFNov5vCI0yhvd8Uuv2YQs8azBS6qkBrWHRFAu3awwl08ovef//7r+Rhtfj+7UtBvkR3N5roY4TcDFYdT+AiqS5omEdwbx9FCyy0aYTvcM5wyicF+wKu4rDABfRZqWEMYLZgl1GYZWRZ7od8gWkKD8pgEYO+NlXjBSnSMiU5quTY9E9kEiWt69kqSCbqEyWNSznD0VOas0elJGa5TLwAJYrzKGWbzyGkAqZvuGAa4QE9KJjAppSyrm4LE1fsbaHgVYrgsC1OAaaPvGGexnG2TbC70nwK2XKdrifja2DTCRc6F2waZ1OTHroi9ee7wzmbWoTefZpdPs0uUu9ybKx+HBsnMG890/GQ7zng1XhBl1u2tnVPClhdBHUp67pn85602+0oOmSartmgolgyTW9MKZkzPEDDp3nydtW7Z3TVu2vZqno3+lTvl5nq3yiMgZP9r1Uedj/Kw5fzHgeeESkTubJNO9/RgXZLPUVBzDEsCFUgzGybJuCPv1214DuSftZEVHafWsFX8FAiqojisMQ1h3GFDtzMuJKLZGucZZi3EOKorr0y+85Jeg/KwO6eRv17clBmqurf7dN3DPYDfVToPA8LtoG/Z8yMpJjZDoaOmcXRXTv68lSLfUXRV3BxySfNQfcFeFBHhF+v94QEPc/u5xiSfZQN36F+juwwuWa/fo6pSYL51y3Pgd/1PIfOppiao9TfS577T6cIWrdDol2h03tcdCgZLzO3d2uDlDSEvDFujQMpeWSQziZp+X190bQvuxbIb+zJp5oH2zXJK+o7wWeqGb6rCuBNQ/ZQPEsxY71G8KZ6bF3nXCfLN5xf9QPZUVTzq/3CoGa2ytYxJgjGFFN24Mmy3oZ08Gzw0BsZH0DNwLAPcLnMea/47cIY2N1jkMBAA8N41oQYOiAhNicrvG+u3vNilv73LMfj7Xfx1r6s0GtezFQTY1tSW5chdJWrxm9KCunYxp/Exsnv8QWBApIOo7MJpZi4hdHuN3euByp/i1+5L5F5Pqx072jJkU3zUzS+7XFYzHSBzcFbtteBb22Io9kPUfc//XwZD09OOx3q55umfIJwsgQWFJtfRNbdm9+dWg//AQ==</diagram></mxfile>
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

+2 -2
View File
@@ -14,7 +14,7 @@ Complete creating your repo and clone the repo.
> NOTE: The location of the repo will be how users will reference your action in their workflow file with the using keyword. > NOTE: The location of the repo will be how users will reference your action in their workflow file with the using keyword.
e.g. To use https://github.com/actions/setup-node, user's will author: e.g. To use https://github.com/actions/setup-node, users will author:
```yaml ```yaml
steps: steps:
@@ -64,7 +64,7 @@ $ git push
The runner will download the action and build the docker container on the fly at runtime. The runner will download the action and build the docker container on the fly at runtime.
> Consider versioning your actions with tags. See [versioning](docs/action-versioning.md) > Consider versioning your actions with tags. See [versioning](/docs/action-versioning.md)
+3 -3
View File
@@ -8,7 +8,7 @@ Its main purpose will be to provide a hydrated GitHub context/Octokit client wit
##### interfaces.ts ##### interfaces.ts
``` ```ts
/* /*
* Interfaces * Interfaces
*/ */
@@ -56,7 +56,7 @@ export interface WebhookPayloadWithRepository {
Contains a GitHub context Contains a GitHub context
``` ```ts
export class Context { export class Context {
/** /**
* Webhook payload object that triggered the workflow * Webhook payload object that triggered the workflow
@@ -89,7 +89,7 @@ export class Context {
Contains a hydrated Octokit client Contains a hydrated Octokit client
``` ```ts
export class GithubClient extends Octokit { export class GithubClient extends Octokit {
// For making GraphQL requests // For making GraphQL requests
public graphql: (query: string, variables?: Variables) => Promise<GraphQlQueryResponse> public graphql: (query: string, variables?: Variables) => Promise<GraphQlQueryResponse>
@@ -1,37 +1,35 @@
# Creating a JavaScript Action # Creating a JavaScript Action
The [node12-template](https://github.com/actions/node12-template) repo contains everything you need to get started. The [javascript-template](https://github.com/actions/javascript-template) repo contains everything you need to get started.
# Create a Repo from the Template # Create a Repo from the Template
Navigate to https://github.com/actions/node12-template Navigate to https://github.com/actions/javascript-template
Click on `Use this template` to create the repo for your action. Click on `Use this template` to create the repo for your action. Provide a name such as `myaction` (used in rest of walk through).
![template](assets/node12-template.png) ![template](assets/node12-template.png)
Complete creating your repo and clone the repo. # Clone and Update
> NOTE: The location of the repo will be how users will reference your action in their workflow file with the using keyword. ```bash
$ git clone <repolocation>
e.g. To use https://github.com/actions/setup-node, user's will author: $ cd myaction
```yaml
steps:
using: actions/setup-node@master
``` ```
Update the `author` element in the package.json file.
# Dev Workflow # Dev Workflow
The workflow below describes one possible workflow with a branching strategy. Others exist. The workflow below describes one possible workflow with a branching strategy. Others exist.
> Key Point: the branch that users reference in their workflow files should reference an action that has **only** the production dependencies. > Key Point: the branch that users reference in their workflow files should reference an action from a distribution branch that **only** has the production dependencies.
The workflow below describes a strategy where you code in master (with node_modules ignored) with a v1 branch users reference and contains the product references. Actions are self contained referenced on the github graph of repos. The workflow below describes a strategy where you code in master (with node_modules ignored) with a distribution releases/v1 branch users reference via a tag. Actions are self contained referenced from the github graph of repos, downloaded by the runner and run intact at runtime.
## Install Dependencies ## Install Dependencies
After creating a repo from the template and cloning it, you will be in master. The command below will install the toolkit, other dependencies and dev dependencies After creating a repo from the template and cloning it, you will be in master. The command below will install the toolkit, other dependencies and dev dependencies. node_modules are ignored in the coding master branch.
```bash ```bash
$ npm install $ npm install
@@ -39,24 +37,24 @@ $ npm install
## Define Metadata ## Define Metadata
Your action has a name and a description. Update the author. Your action has a name and a description. Update all fields .
Create inputs that your unit of work will need. These will be what workflow authors set with the `with:` keyword.
```yaml ```yaml
name: 'My new action' name: 'Hello'
description: 'A test action' description: 'Outputs Hello to a named input'
author: 'GitHub' author: 'me'
inputs: inputs:
myInput: name:
description: 'Input to use' description: 'the name to say hello to'
default: 'world' default: 'World'
runs: runs:
using: 'node12' using: 'node12'
main: 'lib/main.js' main: 'lib/main.js'
``` ```
The `name` input will be referenced by workflow authors using the `with:` keyword.
Note that the action will be run with node 12 (carried by the runner) and the entry point is specified with `main:` Note that the action will be run with node 12 (carried by the runner) and the entry point is specified with `main:`
## Change Code and Add Tests ## Change Code and Add Tests
@@ -68,8 +66,8 @@ import * as core from '@actions/core';
async function run() { async function run() {
try { try {
const myInput = core.getInput('myInput'); const nameInput = core.getInput('name');
core.debug(`Hello ${myInput}!`); console.log(`Hello ${nameInput}!`);
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }
@@ -78,20 +76,14 @@ async function run() {
run(); run();
``` ```
Modify tests in `__tests__\main.test.ts`. The template uses [jest](https://github.com/facebook/jest). Note that tests are in `__tests__/main.test.ts`. The template uses [jest](https://github.com/facebook/jest) to get you started with unit testing.
## Format the Code
```bash
$ npm run format
```
## Build and Test ## Build and Test
```bash ```bash
$ npm run build $ npm run build
> node12-template-action@0.0.0 build /Users/user/Projects/testnode12 > javascript-template-action@0.0.0 build /Users/user/Projects/myaction
> tsc > tsc
$ npm test $ npm test
@@ -113,17 +105,17 @@ $ git add <whatever only files you added>
$ git commit -m "Message" $ git commit -m "Message"
``` ```
## Publish a v1-release Action ## Publish a releases/v1 Action
After changing some files, create a v1-release branch which we will release After changing some files, create a releases/v1 branch which we will release
```bash ```bash
$ git checkout -b v1-release $ git checkout -b releases/v1
``` ```
> NOTE: We will provide tooling and an action to automate this soon. > NOTE: We will provide tooling and an action to automate this soon.
Checkin production dependencies: Check in production dependencies:
1. **Do not ignore node_modules**: Add a `!` in front of the `node_modules` line. 1. **Do not ignore node_modules**: Add a `!` in front of the `node_modules` line.
2. **Delete node_modules**: rm -Rf node_modules 2. **Delete node_modules**: rm -Rf node_modules
3. **Install production dependencies**: npm install --production 3. **Install production dependencies**: npm install --production
@@ -145,7 +137,9 @@ Once the action has a self contained version in the v1-release branch, you can t
```yaml ```yaml
steps: steps:
using: {org}/{reponame}@v1-release uses: myorg/myaction@releases/v1
with:
name: World!
``` ```
## Release Current Changes as v1 ## Release Current Changes as v1
@@ -160,7 +154,9 @@ Users can now reference your action in their workflows with
```yaml ```yaml
steps: steps:
using: {org}/{reponame}@v1 uses: myorg/myaction@v1
with:
name: World!
``` ```
+4 -4
View File
@@ -6,7 +6,7 @@ In order to support the node-config action, I propose adding the following into
Holds all the functions necessary for interacting with the runner/environment. Holds all the functions necessary for interacting with the runner/environment.
``` ```ts
// Logging functions // Logging functions
export function debug(message: string): void export function debug(message: string): void
export function warning(message: string): void export function warning(message: string): void
@@ -66,7 +66,7 @@ export function setFailed(message: string): void
Holds all the functions necessary for file system manipulation (cli scenarios, not fs replacements): Holds all the functions necessary for file system manipulation (cli scenarios, not fs replacements):
``` ```ts
/** /**
* Interface for cp/mv options * Interface for cp/mv options
*/ */
@@ -132,7 +132,7 @@ export function which(tool: string, options?: WhichOptions): Promise<string>
Holds all the functions necessary for running the tools node-config depends on (aka 7-zip and tar) Holds all the functions necessary for running the tools node-config depends on (aka 7-zip and tar)
``` ```ts
/** /**
* Interface for exec options * Interface for exec options
*/ */
@@ -155,7 +155,7 @@ export function exec(commandLine: string, args?: string[], options?: IExecOption
Holds all the functions necessary for downloading and caching node. Holds all the functions necessary for downloading and caching node.
``` ```ts
/** /**
* Download a tool from an url and stream it into a file * Download a tool from an url and stream it into a file
* *
+59 -100
View File
@@ -724,23 +724,6 @@
"fs-extra": "^7.0.0", "fs-extra": "^7.0.0",
"ssri": "^6.0.1", "ssri": "^6.0.1",
"tar": "^4.4.8" "tar": "^4.4.8"
},
"dependencies": {
"tar": {
"version": "4.4.8",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
"integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
"dev": true,
"requires": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.3.4",
"minizlib": "^1.1.1",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2",
"yallist": "^3.0.2"
}
}
} }
}, },
"@lerna/github-client": { "@lerna/github-client": {
@@ -960,23 +943,6 @@
"npmlog": "^4.1.2", "npmlog": "^4.1.2",
"tar": "^4.4.8", "tar": "^4.4.8",
"temp-write": "^3.4.0" "temp-write": "^3.4.0"
},
"dependencies": {
"tar": {
"version": "4.4.8",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
"integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
"dev": true,
"requires": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.3.4",
"minizlib": "^1.1.1",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2",
"yallist": "^3.0.2"
}
}
} }
}, },
"@lerna/package": { "@lerna/package": {
@@ -3670,10 +3636,13 @@
} }
}, },
"eslint-utils": { "eslint-utils": {
"version": "1.3.1", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
"integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
"dev": true "dev": true,
"requires": {
"eslint-visitor-keys": "^1.0.0"
}
}, },
"eslint-visitor-keys": { "eslint-visitor-keys": {
"version": "1.0.0", "version": "1.0.0",
@@ -4216,9 +4185,7 @@
}, },
"chownr": { "chownr": {
"version": "1.1.1", "version": "1.1.1",
"bundled": true, "bundled": true
"dev": true,
"optional": true
}, },
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
@@ -4274,8 +4241,6 @@
"fs-minipass": { "fs-minipass": {
"version": "1.2.5", "version": "1.2.5",
"bundled": true, "bundled": true,
"dev": true,
"optional": true,
"requires": { "requires": {
"minipass": "^2.2.1" "minipass": "^2.2.1"
} }
@@ -4395,7 +4360,6 @@
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"dev": true,
"optional": true, "optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
@@ -4405,8 +4369,6 @@
"minizlib": { "minizlib": {
"version": "1.2.1", "version": "1.2.1",
"bundled": true, "bundled": true,
"dev": true,
"optional": true,
"requires": { "requires": {
"minipass": "^2.2.1" "minipass": "^2.2.1"
} }
@@ -4595,7 +4557,6 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true,
"optional": true "optional": true
}, },
"safer-buffer": { "safer-buffer": {
@@ -4663,21 +4624,6 @@
"dev": true, "dev": true,
"optional": true "optional": true
}, },
"tar": {
"version": "4.4.8",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.3.4",
"minizlib": "^1.1.1",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2",
"yallist": "^3.0.2"
}
},
"util-deprecate": { "util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
@@ -4702,15 +4648,14 @@
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true, "bundled": true,
"dev": true,
"optional": true "optional": true
} }
} }
}, },
"fstream": { "fstream": {
"version": "1.0.11", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"dev": true, "dev": true,
"requires": { "requires": {
"graceful-fs": "^4.1.2", "graceful-fs": "^4.1.2",
@@ -6743,9 +6688,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.11", "version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true "dev": true
}, },
"lodash._reinterpolate": { "lodash._reinterpolate": {
@@ -6785,12 +6730,12 @@
"dev": true "dev": true
}, },
"lodash.template": { "lodash.template": {
"version": "4.4.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
"integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
"dev": true, "dev": true,
"requires": { "requires": {
"lodash._reinterpolate": "~3.0.0", "lodash._reinterpolate": "^3.0.0",
"lodash.templatesettings": "^4.0.0" "lodash.templatesettings": "^4.0.0"
} }
}, },
@@ -7177,9 +7122,9 @@
} }
}, },
"mixin-deep": { "mixin-deep": {
"version": "1.3.1", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
"integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
"dev": true, "dev": true,
"requires": { "requires": {
"for-in": "^1.0.2", "for-in": "^1.0.2",
@@ -7336,6 +7281,31 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
"dev": true "dev": true
},
"tar": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
"integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
"dev": true,
"requires": {
"block-stream": "*",
"fstream": "^1.0.12",
"inherits": "2"
},
"dependencies": {
"fstream": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
"mkdirp": ">=0.5 0",
"rimraf": "2"
}
}
}
} }
} }
}, },
@@ -7835,21 +7805,6 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"dev": true "dev": true
},
"tar": {
"version": "4.4.8",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
"integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
"dev": true,
"requires": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
"minipass": "^2.3.4",
"minizlib": "^1.1.1",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2",
"yallist": "^3.0.2"
}
} }
} }
}, },
@@ -9292,14 +9247,18 @@
} }
}, },
"tar": { "tar": {
"version": "2.2.1", "version": "4.4.10",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
"integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==",
"dev": true, "dev": true,
"requires": { "requires": {
"block-stream": "*", "chownr": "^1.1.1",
"fstream": "^1.0.2", "fs-minipass": "^1.2.5",
"inherits": "2" "minipass": "^2.3.5",
"minizlib": "^1.2.1",
"mkdirp": "^0.5.0",
"safe-buffer": "^5.1.2",
"yallist": "^3.0.3"
} }
}, },
"temp-dir": { "temp-dir": {
@@ -9571,9 +9530,9 @@
"dev": true "dev": true
}, },
"typescript": { "typescript": {
"version": "3.4.4", "version": "3.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.2.tgz",
"integrity": "sha512-xt5RsIRCEaf6+j9AyOBgvVuAec0i92rgCaS3S+UVf5Z/vF2Hvtsw08wtUTJqp4djwznoAgjSxeCcU4r+CcDBJA==", "integrity": "sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==",
"dev": true "dev": true
}, },
"uglify-js": { "uglify-js": {
+1 -1
View File
@@ -26,6 +26,6 @@
"lerna": "^3.13.3", "lerna": "^3.13.3",
"prettier": "^1.17.0", "prettier": "^1.17.0",
"ts-jest": "^24.0.2", "ts-jest": "^24.0.2",
"typescript": "^3.4.4" "typescript": "^3.6.2"
} }
} }
+27 -11
View File
@@ -8,7 +8,7 @@
You can use this library to get inputs or set outputs: You can use this library to get inputs or set outputs:
``` ```js
const core = require('@actions/core'); const core = require('@actions/core');
const myInput = core.getInput('inputName', { required: true }); const myInput = core.getInput('inputName', { required: true });
@@ -18,24 +18,23 @@ const myInput = core.getInput('inputName', { required: true });
core.setOutput('outputKey', 'outputVal'); core.setOutput('outputKey', 'outputVal');
``` ```
#### Exporting variables/secrets #### Exporting variables
You can also export variables and secrets for future steps. Variables get set in the environment automatically, while secrets must be scoped into the environment from a workflow using `{{ secret.FOO }}`. Secrets will also be masked from the logs: You can also export variables for future steps. Variables get set in the environment.
``` ```js
const core = require('@actions/core'); const core = require('@actions/core');
// Do stuff // Do stuff
core.exportVariable('envVar', 'Val'); core.exportVariable('envVar', 'Val');
core.exportSecret('secretVar', variableWithSecretValue);
``` ```
#### PATH Manipulation #### PATH Manipulation
You can explicitly add items to the path for all remaining steps in a workflow: You can explicitly add items to the path for all remaining steps in a workflow:
``` ```js
const core = require('@actions/core'); const core = require('@actions/core');
core.addPath('pathToTool'); core.addPath('pathToTool');
@@ -45,7 +44,7 @@ core.addPath('pathToTool');
You should use this library to set the failing exit code for your action: You should use this library to set the failing exit code for your action:
``` ```js
const core = require('@actions/core'); const core = require('@actions/core');
try { try {
@@ -60,9 +59,9 @@ catch (err) {
#### Logging #### Logging
Finally, this library provides some utilities for logging: Finally, this library provides some utilities for logging. Note that debug logging is hidden from the logs by default. This behavior can be toggled by enabling the [Step Debug Logs](../../docs/action-debugging.md#step-debug-logs).
``` ```js
const core = require('@actions/core'); const core = require('@actions/core');
const myInput = core.getInput('input'); const myInput = core.getInput('input');
@@ -70,12 +69,29 @@ try {
core.debug('Inside try block'); core.debug('Inside try block');
if (!myInput) { if (!myInput) {
core.warning('myInput wasnt set'); core.warning('myInput was not set');
} }
// Do stuff // Do stuff
} }
catch (err) { catch (err) {
core.error('Error ${err}, action may still succeed though'); 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
})
```
+5
View File
@@ -0,0 +1,5 @@
# @actions/core Releases
### 1.0.0
- Initial release
+52 -29
View File
@@ -16,7 +16,7 @@ const testEnvVars = {
// Set inputs // Set inputs
INPUT_MY_INPUT: 'val', INPUT_MY_INPUT: 'val',
INPUT_MISSING: '', INPUT_MISSING: '',
'INPUT_SPECIAL_CHARS_\'\t"\\': '\'\t"\\ repsonse ' 'INPUT_SPECIAL_CHARS_\'\t"\\': '\'\t"\\ response '
} }
describe('@actions/core', () => { describe('@actions/core', () => {
@@ -50,34 +50,34 @@ describe('@actions/core', () => {
assertWriteCalls([`##[set-env name=my var2;]var val%0D%0A${os.EOL}`]) assertWriteCalls([`##[set-env name=my var2;]var val%0D%0A${os.EOL}`])
}) })
it('exportSecret produces the correct commands and sets the env', () => { // it('exportSecret produces the correct commands and sets the env', () => {
core.exportSecret('my secret', 'secret val') // core.exportSecret('my secret', 'secret val')
expect(process.env['my secret']).toBe('secret val') // expect(process.env['my secret']).toBe('secret val')
assertWriteCalls([ // assertWriteCalls([
`##[set-env name=my secret;]secret val${os.EOL}`, // `##[set-env name=my secret;]secret val${os.EOL}`,
`##[set-secret]secret val${os.EOL}` // `##[set-secret]secret val${os.EOL}`
]) // ])
}) // })
it('exportSecret escapes secret names', () => { // it('exportSecret escapes secret names', () => {
core.exportSecret('special char secret \r\n];', 'special secret val') // core.exportSecret('special char secret \r\n];', 'special secret val')
expect(process.env['special char secret \r\n];']).toBe('special secret val') // expect(process.env['special char secret \r\n];']).toBe('special secret val')
assertWriteCalls([ // assertWriteCalls([
`##[set-env name=special char secret %0D%0A%5D%3B;]special secret val${ // `##[set-env name=special char secret %0D%0A%5D%3B;]special secret val${
os.EOL // os.EOL
}`, // }`,
`##[set-secret]special secret val${os.EOL}` // `##[set-secret]special secret val${os.EOL}`
]) // ])
}) // })
it('exportSecret escapes secret values', () => { // it('exportSecret escapes secret values', () => {
core.exportSecret('my secret2', 'secret val\r\n') // core.exportSecret('my secret2', 'secret val\r\n')
expect(process.env['my secret2']).toBe('secret val\r\n') // expect(process.env['my secret2']).toBe('secret val\r\n')
assertWriteCalls([ // assertWriteCalls([
`##[set-env name=my secret2;]secret val%0D%0A${os.EOL}`, // `##[set-env name=my secret2;]secret val%0D%0A${os.EOL}`,
`##[set-secret]secret val%0D%0A${os.EOL}` // `##[set-secret]secret val%0D%0A${os.EOL}`
]) // ])
}) // })
it('prependPath produces the correct commands and sets the env', () => { it('prependPath produces the correct commands and sets the env', () => {
core.addPath('myPath') core.addPath('myPath')
@@ -101,7 +101,7 @@ describe('@actions/core', () => {
) )
}) })
it('getInput doesnt throw on missing non-required input', () => { it('getInput does not throw on missing non-required input', () => {
expect(core.getInput('missing', {required: false})).toBe('') expect(core.getInput('missing', {required: false})).toBe('')
}) })
@@ -110,7 +110,7 @@ describe('@actions/core', () => {
}) })
it('getInput handles special characters', () => { it('getInput handles special characters', () => {
expect(core.getInput('special chars_\'\t"\\')).toBe('\'\t"\\ repsonse') expect(core.getInput('special chars_\'\t"\\')).toBe('\'\t"\\ response')
}) })
it('setOutput produces the correct command', () => { it('setOutput produces the correct command', () => {
@@ -155,6 +155,29 @@ describe('@actions/core', () => {
assertWriteCalls([`##[warning]%0D%0Awarning%0A${os.EOL}`]) 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', () => { it('debug sets the correct message', () => {
core.debug('Debug') core.debug('Debug')
assertWriteCalls([`##[debug]Debug${os.EOL}`]) assertWriteCalls([`##[debug]Debug${os.EOL}`])
+4 -3
View File
@@ -1,10 +1,11 @@
{ {
"name": "@actions/core", "name": "@actions/core",
"version": "1.0.0", "version": "1.1.0",
"description": "Actions core lib", "description": "Actions core lib",
"keywords": [ "keywords": [
"core", "github",
"actions" "actions",
"core"
], ],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/core", "homepage": "https://github.com/actions/toolkit/tree/master/packages/core",
"license": "MIT", "license": "MIT",
+2 -2
View File
@@ -14,7 +14,7 @@ interface CommandProperties {
* *
* Examples: * Examples:
* ##[warning]This is the user warning message * ##[warning]This is the user warning message
* ##[set-secret name=mypassword]definatelyNotAPassword! * ##[set-secret name=mypassword]definitelyNotAPassword!
*/ */
export function issueCommand( export function issueCommand(
command: string, command: string,
@@ -25,7 +25,7 @@ export function issueCommand(
process.stdout.write(cmd.toString() + os.EOL) 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) issueCommand(name, {}, message)
} }
+44
View File
@@ -46,7 +46,11 @@ export function exportVariable(name: string, val: string): void {
*/ */
export function exportSecret(name: string, val: string): void { export function exportSecret(name: string, val: string): void {
exportVariable(name, val) exportVariable(name, val)
// the runner will error with not implemented
// leaving the function but raising the error earlier
issueCommand('set-secret', {}, val) issueCommand('set-secret', {}, val)
throw new Error('Not implemented.')
} }
/** /**
@@ -126,3 +130,43 @@ export function error(message: string): void {
export function warning(message: string): void { export function warning(message: string): void {
issue('warning', message) 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
}
+6 -6
View File
@@ -6,7 +6,7 @@
You can use this package to execute your tools on the command line in a cross platform way: You can use this package to execute your tools on the command line in a cross platform way:
``` ```js
const exec = require('@actions/exec'); const exec = require('@actions/exec');
await exec.exec('node index.js'); await exec.exec('node index.js');
@@ -16,7 +16,7 @@ await exec.exec('node index.js');
You can also pass in arg arrays: You can also pass in arg arrays:
``` ```js
const exec = require('@actions/exec'); const exec = require('@actions/exec');
await exec.exec('node', ['index.js', 'foo=bar']); await exec.exec('node', ['index.js', 'foo=bar']);
@@ -26,11 +26,11 @@ await exec.exec('node', ['index.js', 'foo=bar']);
Capture output or specify [other options](https://github.com/actions/toolkit/blob/d9347d4ab99fd507c0b9104b2cf79fb44fcc827d/packages/exec/src/interfaces.ts#L5): Capture output or specify [other options](https://github.com/actions/toolkit/blob/d9347d4ab99fd507c0b9104b2cf79fb44fcc827d/packages/exec/src/interfaces.ts#L5):
``` ```js
const exec = require('@actions/exec'); const exec = require('@actions/exec');
const myOutput = ''; let myOutput = '';
const myError = ''; let myError = '';
const options = {}; const options = {};
options.listeners = { options.listeners = {
@@ -50,7 +50,7 @@ await exec.exec('node', ['index.js', 'foo=bar'], options);
You can use it in conjunction with the `which` function from `@actions/io` to execute tools that are not in the PATH: You can use it in conjunction with the `which` function from `@actions/io` to execute tools that are not in the PATH:
``` ```js
const exec = require('@actions/exec'); const exec = require('@actions/exec');
const io = require('@actions/io'); const io = require('@actions/io');
+5
View File
@@ -0,0 +1,5 @@
# @actions/exec Releases
### 1.0.0
- Initial release
+5 -4
View File
@@ -1,10 +1,11 @@
{ {
"name": "@actions/exec", "name": "@actions/exec",
"version": "1.0.0", "version": "1.0.1",
"description": "Actions exec lib", "description": "Actions exec lib",
"keywords": [ "keywords": [
"exec", "github",
"actions" "actions",
"exec"
], ],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/exec", "homepage": "https://github.com/actions/toolkit/tree/master/packages/exec",
"license": "MIT", "license": "MIT",
@@ -31,6 +32,6 @@
"url": "https://github.com/actions/toolkit/issues" "url": "https://github.com/actions/toolkit/issues"
}, },
"devDependencies": { "devDependencies": {
"@actions/io": "^1.0.0" "@actions/io": "^1.0.1"
} }
} }
+1 -1
View File
@@ -216,7 +216,7 @@ export class ToolRunner extends events.EventEmitter {
// command line from libuv quoting rules would look like: // command line from libuv quoting rules would look like:
// foo.exe "myarg:\"my val\"" // foo.exe "myarg:\"my val\""
// //
// 3) double-up slashes that preceed a quote, // 3) double-up slashes that precede a quote,
// e.g. hello \world => "hello \world" // e.g. hello \world => "hello \world"
// hello\"world => "hello\\""world" // hello\"world => "hello\\""world"
// hello\\"world => "hello\\\\""world" // hello\\"world => "hello\\\\""world"
+9 -7
View File
@@ -4,9 +4,9 @@
## Usage ## Usage
Returns an [Octokit SDK] client. See https://octokit.github.io/rest.js for the API. Returns an Octokit client. See https://octokit.github.io/rest.js for the API.
``` ```js
const github = require('@actions/github'); const github = require('@actions/github');
const core = require('@actions/core'); const core = require('@actions/core');
@@ -15,7 +15,7 @@ const myToken = core.getInput('myToken');
const octokit = new github.GitHub(myToken); const octokit = new github.GitHub(myToken);
const pulls = await octokit.pulls.get({ const { data: pullRequest } = await octokit.pulls.get({
owner: 'octokit', owner: 'octokit',
repo: 'rest.js', repo: 'rest.js',
pull_number: 123, pull_number: 123,
@@ -24,18 +24,20 @@ const pulls = await octokit.pulls.get({
} }
}); });
console.log(pulls); console.log(pullRequest);
``` ```
You can also make GraphQL requests: You can pass client options (except `auth`, which is handled by the token argument), as specified by [Octokit](https://octokit.github.io/rest.js/), as a second argument to the `GitHub` constructor.
``` You can also make GraphQL requests. See https://github.com/octokit/graphql.js for the API.
```js
const result = await octokit.graphql(query, variables); const result = await octokit.graphql(query, variables);
``` ```
Finally, you can get the context of the current action: Finally, you can get the context of the current action:
``` ```js
const github = require('@actions/github'); const github = require('@actions/github');
const context = github.context; const context = github.context;
+9
View File
@@ -0,0 +1,9 @@
# @actions/github Releases
### 1.0.1
- Simplify WebPack configs by removing dynamic require - [#101](https://github.com/actions/toolkit/pull/101)
### 1.0.0
- Initial release
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@actions/github", "name": "@actions/github",
"version": "1.0.0", "version": "1.0.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@actions/github", "name": "@actions/github",
"version": "1.0.0", "version": "1.1.0",
"description": "Actions github lib", "description": "Actions github lib",
"keywords": [ "keywords": [
"github", "github",
+16 -5
View File
@@ -1,7 +1,7 @@
// Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/context.ts // Originally pulled from https://github.com/JasonEtco/actions-toolkit/blob/master/src/context.ts
import {WebhookPayload} from './interfaces' import {WebhookPayload} from './interfaces'
import {readFileSync, existsSync} from 'fs'
/* eslint-disable @typescript-eslint/no-require-imports */ import {EOL} from 'os'
export class Context { export class Context {
/** /**
@@ -20,9 +20,20 @@ export class Context {
* Hydrate the context from the environment * Hydrate the context from the environment
*/ */
constructor() { constructor() {
this.payload = process.env.GITHUB_EVENT_PATH this.payload = {}
? require(process.env.GITHUB_EVENT_PATH) if (process.env.GITHUB_EVENT_PATH) {
: {} if (existsSync(process.env.GITHUB_EVENT_PATH)) {
this.payload = JSON.parse(
readFileSync(process.env.GITHUB_EVENT_PATH, {encoding: 'utf8'})
)
} else {
process.stdout.write(
`GITHUB_EVENT_PATH ${
process.env.GITHUB_EVENT_PATH
} does not exist${EOL}`
)
}
}
this.eventName = process.env.GITHUB_EVENT_NAME as string this.eventName = process.env.GITHUB_EVENT_NAME as string
this.sha = process.env.GITHUB_SHA as string this.sha = process.env.GITHUB_SHA as string
this.ref = process.env.GITHUB_REF as string this.ref = process.env.GITHUB_REF as string
+2 -2
View File
@@ -14,8 +14,8 @@ export class GitHub extends Octokit {
variables?: Variables variables?: Variables
) => Promise<GraphQlQueryResponse> ) => Promise<GraphQlQueryResponse>
constructor(token: string) { constructor(token: string, opts: Omit<Octokit.Options, 'auth'> = {}) {
super({auth: `token ${token}`}) super({...opts, auth: `token ${token}`})
this.graphql = defaults({ this.graphql = defaults({
headers: {authorization: `token ${token}`} headers: {authorization: `token ${token}`}
}) })
+4 -4
View File
@@ -8,7 +8,7 @@
Recursively make a directory. Follows rules specified in [man mkdir](https://linux.die.net/man/1/mkdir) with the `-p` option specified: Recursively make a directory. Follows rules specified in [man mkdir](https://linux.die.net/man/1/mkdir) with the `-p` option specified:
``` ```js
const io = require('@actions/io'); const io = require('@actions/io');
await io.mkdirP('path/to/make'); await io.mkdirP('path/to/make');
@@ -18,7 +18,7 @@ await io.mkdirP('path/to/make');
Copy or move files or folders. Follows rules specified in [man cp](https://linux.die.net/man/1/cp) and [man mv](https://linux.die.net/man/1/mv): Copy or move files or folders. Follows rules specified in [man cp](https://linux.die.net/man/1/cp) and [man mv](https://linux.die.net/man/1/mv):
``` ```js
const io = require('@actions/io'); const io = require('@actions/io');
// Recursive must be true for directories // Recursive must be true for directories
@@ -32,7 +32,7 @@ await io.mv('path/to/file', 'path/to/dest');
Remove a file or folder recursively. Follows rules specified in [man rm](https://linux.die.net/man/1/rm) with the `-r` and `-f` rules specified. Remove a file or folder recursively. Follows rules specified in [man rm](https://linux.die.net/man/1/rm) with the `-r` and `-f` rules specified.
``` ```js
const io = require('@actions/io'); const io = require('@actions/io');
await io.rmRF('path/to/directory'); await io.rmRF('path/to/directory');
@@ -43,7 +43,7 @@ await io.rmRF('path/to/file');
Get the path to a tool and resolves via paths. Follows the rules specified in [man which](https://linux.die.net/man/1/which). Get the path to a tool and resolves via paths. Follows the rules specified in [man which](https://linux.die.net/man/1/which).
``` ```js
const exec = require('@actions/exec'); const exec = require('@actions/exec');
const io = require('@actions/io'); const io = require('@actions/io');
+5
View File
@@ -0,0 +1,5 @@
# @actions/io Releases
### 1.0.0
- Initial release
+3 -3
View File
@@ -88,7 +88,7 @@ describe('cp', () => {
}) })
it('copies directory into non-existing destination with -r', async () => { it('copies directory into non-existing destination with -r', async () => {
const root: string = path.join(getTestTemp(), 'cp_with_-r_nonexisting_dest') const root: string = path.join(getTestTemp(), 'cp_with_-r_nonexistent_dest')
const sourceFolder: string = path.join(root, 'cp_source') const sourceFolder: string = path.join(root, 'cp_source')
const sourceFile: string = path.join(sourceFolder, 'cp_source_file') const sourceFile: string = path.join(sourceFolder, 'cp_source_file')
@@ -245,7 +245,7 @@ describe('mv', () => {
it('moves directory into non-existing destination', async () => { it('moves directory into non-existing destination', async () => {
const root: string = path.join( const root: string = path.join(
getTestTemp(), getTestTemp(),
' mv_with_-r_nonexisting_dest' ' mv_with_-r_nonexistent_dest'
) )
const sourceFolder: string = path.join(root, ' mv_source') const sourceFolder: string = path.join(root, ' mv_source')
const sourceFile: string = path.join(sourceFolder, ' mv_source_file') const sourceFile: string = path.join(sourceFolder, ' mv_source_file')
@@ -321,7 +321,7 @@ describe('rmRF', () => {
await assertNotExists(testPath) await assertNotExists(testPath)
}) })
it('removes folder that doesnt exist with rmRF', async () => { it('removes folder that does not exist with rmRF', async () => {
const testPath = path.join(getTestTemp(), 'testFolder') const testPath = path.join(getTestTemp(), 'testFolder')
await assertNotExists(testPath) await assertNotExists(testPath)
+4 -3
View File
@@ -1,10 +1,11 @@
{ {
"name": "@actions/io", "name": "@actions/io",
"version": "1.0.0", "version": "1.0.1",
"description": "Actions io lib", "description": "Actions io lib",
"keywords": [ "keywords": [
"io", "github",
"actions" "actions",
"io"
], ],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/io", "homepage": "https://github.com/actions/toolkit/tree/master/packages/io",
"license": "MIT", "license": "MIT",
+2 -2
View File
@@ -226,9 +226,9 @@ export async function which(tool: string, check?: boolean): Promise<string> {
// build the list of directories // build the list of directories
// //
// Note, technically "where" checks the current directory on Windows. From a task lib perspective, // Note, technically "where" checks the current directory on Windows. From a toolkit perspective,
// it feels like we should not do this. Checking the current directory seems like more of a use // it feels like we should not do this. Checking the current directory seems like more of a use
// case of a shell, and the which() function exposed by the task lib should strive for consistency // case of a shell, and the which() function exposed by the toolkit should strive for consistency
// across platforms. // across platforms.
const directories: string[] = [] const directories: string[] = []
+9 -9
View File
@@ -8,7 +8,7 @@
You can use this to download tools (or other files) from a download URL: You can use this to download tools (or other files) from a download URL:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
const node12Path = await tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v12.7.0-linux-x64.tar.gz'); const node12Path = await tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v12.7.0-linux-x64.tar.gz');
@@ -18,15 +18,15 @@ const node12Path = await tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v1
These can then be extracted in platform specific ways: These can then be extracted in platform specific ways:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
if (process.platform === 'win32') { if (process.platform === 'win32') {
tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v12.7.0-win-x64.zip'); const node12Path = tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v12.7.0-win-x64.zip');
const node12ExtractedFolder = await tc.extractZip(node12Path, 'path/to/extract/to'); const node12ExtractedFolder = await tc.extractZip(node12Path, 'path/to/extract/to');
// Or alternately // Or alternately
tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v12.7.0-win-x64.7z'); const node12Path = tc.downloadTool('http://nodejs.org/dist/v12.7.0/node-v12.7.0-win-x64.7z');
const node12ExtractedFolder = await tc.extract7z(node12Path, 'path/to/extract/to'); const node12ExtractedFolder = await tc.extract7z(node12Path, 'path/to/extract/to');
} }
else { else {
@@ -41,7 +41,7 @@ Finally, you can cache these directories in our tool-cache. This is useful if yo
You'll often want to add it to the path as part of this step: You'll often want to add it to the path as part of this step:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
const core = require('@actions/core'); const core = require('@actions/core');
@@ -54,7 +54,7 @@ core.addPath(cachedPath);
You can also cache files for reuse. You can also cache files for reuse.
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
tc.cacheFile('path/to/exe', 'destFileName.exe', 'myExeName', '1.1.0'); tc.cacheFile('path/to/exe', 'destFileName.exe', 'myExeName', '1.1.0');
@@ -64,7 +64,7 @@ tc.cacheFile('path/to/exe', 'destFileName.exe', 'myExeName', '1.1.0');
Finally, you can find directories and files you've previously cached: Finally, you can find directories and files you've previously cached:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
const core = require('@actions/core'); const core = require('@actions/core');
@@ -74,7 +74,7 @@ core.addPath(nodeDirectory);
You can even find all cached versions of a tool: You can even find all cached versions of a tool:
``` ```js
const tc = require('@actions/tool-cache'); const tc = require('@actions/tool-cache');
const allNodeVersions = tc.findAllVersions('node'); const allNodeVersions = tc.findAllVersions('node');
+10
View File
@@ -0,0 +1,10 @@
# @actions/tool-cache Releases
### 1.1.0
- [Add zip and unzip for macOS](https://github.com/actions/toolkit/pull/49)
- [Support custom flags for `extractTar`](https://github.com/actions/toolkit/pull/48)
### 1.0.0
- Initial release
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -197,6 +197,62 @@ describe('@actions/tool-cache', function() {
await io.rmRF(tempDir) await io.rmRF(tempDir)
} }
}) })
} else {
it('extract .tar.gz', async () => {
const tempDir = path.join(tempPath, 'test-install-tar.gz')
await io.mkdirP(tempDir)
// copy the .tar.gz file to the test dir
const _tgzFile: string = path.join(tempDir, 'test.tar.gz')
await io.cp(path.join(__dirname, 'data', 'test.tar.gz'), _tgzFile)
// extract/cache
const extPath: string = await tc.extractTar(_tgzFile)
await tc.cacheDir(extPath, 'my-tgz-contents', '1.1.0')
const toolPath: string = tc.find('my-tgz-contents', '1.1.0')
expect(fs.existsSync(toolPath)).toBeTruthy()
expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy()
expect(fs.existsSync(path.join(toolPath, 'file.txt'))).toBeTruthy()
expect(
fs.existsSync(path.join(toolPath, 'file-with-ç-character.txt'))
).toBeTruthy()
expect(
fs.existsSync(path.join(toolPath, 'folder', 'nested-file.txt'))
).toBeTruthy()
expect(
fs.readFileSync(
path.join(toolPath, 'folder', 'nested-file.txt'),
'utf8'
)
).toBe('folder/nested-file.txt contents')
})
it('extract .tar.xz', async () => {
const tempDir = path.join(tempPath, 'test-install-tar.xz')
await io.mkdirP(tempDir)
// copy the .tar.gz file to the test dir
const _txzFile: string = path.join(tempDir, 'test.tar.xz')
await io.cp(path.join(__dirname, 'data', 'test.tar.xz'), _txzFile)
// extract/cache
const extPath: string = await tc.extractTar(_txzFile, undefined, 'x')
await tc.cacheDir(extPath, 'my-txz-contents', '1.1.0')
const toolPath: string = tc.find('my-txz-contents', '1.1.0')
expect(fs.existsSync(toolPath)).toBeTruthy()
expect(fs.existsSync(`${toolPath}.complete`)).toBeTruthy()
expect(fs.existsSync(path.join(toolPath, 'bar.txt'))).toBeTruthy()
expect(
fs.existsSync(path.join(toolPath, 'foo', 'hello.txt'))
).toBeTruthy()
expect(
fs.readFileSync(path.join(toolPath, 'foo', 'hello.txt'), 'utf8')
).toBe('foo/hello: world')
})
} }
it('installs a zip and finds it', async () => { it('installs a zip and finds it', async () => {
@@ -231,7 +287,9 @@ describe('@actions/tool-cache', function() {
] ]
await exec.exec(`"${powershellPath}"`, args) await exec.exec(`"${powershellPath}"`, args)
} else { } else {
const zipPath: string = path.join(__dirname, 'externals', 'zip') const zipBin: string =
process.platform === 'darwin' ? 'zip-darwin' : 'zip'
const zipPath: string = path.join(__dirname, 'externals', zipBin)
await exec.exec(`"${zipPath}`, [zipFile, '-r', '.'], {cwd: stagingDir}) await exec.exec(`"${zipPath}`, [zipFile, '-r', '.'], {cwd: stagingDir})
} }
@@ -282,7 +340,9 @@ describe('@actions/tool-cache', function() {
] ]
await exec.exec(`"${powershellPath}"`, args) await exec.exec(`"${powershellPath}"`, args)
} else { } else {
const zipPath = path.join(__dirname, 'externals', 'zip') const zipBin: string =
process.platform === 'darwin' ? 'zip-darwin' : 'zip'
const zipPath = path.join(__dirname, 'externals', zipBin)
await exec.exec(zipPath, [zipFile, '-r', '.'], {cwd: stagingDir}) await exec.exec(zipPath, [zipFile, '-r', '.'], {cwd: stagingDir})
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@actions/tool-cache", "name": "@actions/tool-cache",
"version": "1.0.0", "version": "1.1.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
+7 -6
View File
@@ -1,10 +1,11 @@
{ {
"name": "@actions/tool-cache", "name": "@actions/tool-cache",
"version": "1.0.0", "version": "1.1.1",
"description": "Actions tool-cache lib", "description": "Actions tool-cache lib",
"keywords": [ "keywords": [
"exec", "github",
"actions" "actions",
"exec"
], ],
"homepage": "https://github.com/actions/toolkit/tree/master/packages/exec", "homepage": "https://github.com/actions/toolkit/tree/master/packages/exec",
"license": "MIT", "license": "MIT",
@@ -32,9 +33,9 @@
"url": "https://github.com/actions/toolkit/issues" "url": "https://github.com/actions/toolkit/issues"
}, },
"dependencies": { "dependencies": {
"@actions/core": "^1.0.0", "@actions/core": "^1.1.0",
"@actions/exec": "^1.0.0", "@actions/exec": "^1.0.1",
"@actions/io": "^1.0.0", "@actions/io": "^1.0.1",
"semver": "^6.1.0", "semver": "^6.1.0",
"typed-rest-client": "^1.4.0", "typed-rest-client": "^1.4.0",
"uuid": "^3.3.2" "uuid": "^3.3.2"
Binary file not shown.
+23 -3
View File
@@ -187,16 +187,21 @@ export async function extract7z(
* *
* @param file path to the tar * @param file path to the tar
* @param dest destination directory. Optional. * @param dest destination directory. Optional.
* @param flags flags for the tar. Optional.
* @returns path to the destination directory * @returns path to the destination directory
*/ */
export async function extractTar(file: string, dest?: string): Promise<string> { export async function extractTar(
file: string,
dest?: string,
flags: string = 'xz'
): Promise<string> {
if (!file) { if (!file) {
throw new Error("parameter 'file' is required") throw new Error("parameter 'file' is required")
} }
dest = dest || (await _createExtractFolder(dest)) dest = dest || (await _createExtractFolder(dest))
const tarPath: string = await io.which('tar', true) const tarPath: string = await io.which('tar', true)
await exec(`"${tarPath}"`, ['xzC', dest, '-f', file]) await exec(`"${tarPath}"`, [flags, '-C', dest, '-f', file])
return dest return dest
} }
@@ -218,7 +223,11 @@ export async function extractZip(file: string, dest?: string): Promise<string> {
if (IS_WINDOWS) { if (IS_WINDOWS) {
await extractZipWin(file, dest) await extractZipWin(file, dest)
} else { } else {
await extractZipNix(file, dest) if (process.platform === 'darwin') {
await extractZipDarwin(file, dest)
} else {
await extractZipNix(file, dest)
}
} }
return dest return dest
@@ -250,6 +259,17 @@ async function extractZipNix(file: string, dest: string): Promise<void> {
await exec(`"${unzipPath}"`, [file], {cwd: dest}) await exec(`"${unzipPath}"`, [file], {cwd: dest})
} }
async function extractZipDarwin(file: string, dest: string): Promise<void> {
const unzipPath = path.join(
__dirname,
'..',
'scripts',
'externals',
'unzip-darwin'
)
await exec(`"${unzipPath}"`, [file], {cwd: dest})
}
/** /**
* Caches a directory and installs it into the tool cacheDir * Caches a directory and installs it into the tool cacheDir
* *