-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from codfish/outputs
feat: add new output variables
- Loading branch information
Showing
4 changed files
with
212 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,62 +4,118 @@ | |
> your repo. Exports [environment variables](#outputs) for you to use in subsequent actions | ||
> containing version numbers. | ||
## Why | ||
## Usage | ||
|
||
It would have been fairly easy to run this as a "host action," aka something that simply runs | ||
directly on the VM. | ||
See [action.yml](action.yml) | ||
|
||
- Use major version | ||
([recommended by GitHub](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)): | ||
`uses: codfish/semantic-release-action@v1` | ||
- Use latest version: `uses: codfish/semantic-release-action@master` | ||
- Use specific version: `uses: codfish/[email protected]` | ||
|
||
Basic Usage: | ||
|
||
```yml | ||
steps: | ||
- name: Semantic Release | ||
run: npx semantic-release | ||
- uses: actions/checkout@master | ||
|
||
- uses: codfish/semantic-release-action@master | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
``` | ||
If you're just publishing an node package, then this could still work well for you. The problem I | ||
found with this is when I was in projects where I had subsequent steps/actions in which I wanted to | ||
know whether a new version was cut. | ||
Using output variables set by `semantic-release-action`: | ||
|
||
> **Use Case:** For instance, in an application where I'm using `semantic-release` to manage GitHub | ||
> releases, but also building and pushing docker images. Dockerhub has a | ||
> [nice GitHub integration](https://docs.docker.com/docker-hub/builds/) to handle this for us, but | ||
> some other registries do not. If I need to cut a new release, then update a docker registry by | ||
> adding a new tagged build, I'll want to run `semantic-release` and then build a docker image, tag | ||
> it with a version and push it up. In my case I like to push up tags for `latest`, the semver (i.e. | ||
> `1.8.3`), and just the major the version (i.e. `1`). | ||
```yml | ||
steps: | ||
- uses: actions/checkout@master | ||
I want to know 1) if semantic-release cut a new version and 2) what the version is. | ||
# you'll need to add an `id` in order to access output variables | ||
- uses: codfish/semantic-release-action@master | ||
id: semantic | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
|
||
There's a number of ways to handle this, but the most elegant way I found to do it was to abstract | ||
it into it's own custom action. It abstracts away whatever logic you need to figure out what that | ||
new release number is. | ||
- run: echo ${{ steps.semantic.outputs.release-version }} | ||
|
||
This also scales well, just in case I want to add some flexibility and functionality to this action, | ||
I can easily leverage it across any project. | ||
- run: echo "$OUTPUTS" | ||
env: | ||
OUTPUTS: ${{ toJson(steps.semantic.outputs) }} | ||
|
||
## Usage | ||
- uses: codfish/some-other-action@master | ||
with: | ||
release-version: ${{ steps.semantic.outputs.release-version }} | ||
``` | ||
Only run an action if a new version was created: | ||
```yml | ||
steps: | ||
- uses: actions/checkout@master | ||
|
||
# you'll need to add an `id` in order to access output variables | ||
- uses: codfish/semantic-release-action@master | ||
id: semantic | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
|
||
# exit gracefully if no version was published | ||
- name: docker push version | ||
run: | | ||
if [ "$NEW_RELEASE_PUBLISHED" == "false" ]; then exit 0; fi; | ||
docker tag $DOCKER_REGISTRY/your-image $DOCKER_REGISTRY/your-image:$TAG | ||
docker push $DOCKER_REGISTRY/your-image:$TAG | ||
env: | ||
DOCKER_REGISTRY: ${{ secrets.DOCKER_REGISTRY }} | ||
TAG: v$RELEASE_VERSION | ||
``` | ||
**NOTE**: In theory we'll be able to handle this more gracefully in the future. | ||
[We're not able to access the `steps` context within an `if` expression yet](https://github.com/actions/toolkit/issues/96). | ||
|
||
**DOES NOT WORK YET:** | ||
|
||
```yml | ||
steps: | ||
- uses: actions/checkout@master | ||
- uses: codfish/semantic-release-action@master | ||
id: semantic | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
- if: steps.semantic.outputs.new-release-published == 'true' | ||
run: echo "A new release was published!!" | ||
``` | ||
|
||
Using environment variables set by `semantic-release-action`: | ||
|
||
```yml | ||
jobs: | ||
release: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@master | ||
steps: | ||
- uses: actions/checkout@master | ||
- uses: codfish/semantic-release-action@master | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
- uses: codfish/actions/semantic-release@master | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
- run: | | ||
echo $RELEASE_VERSION | ||
echo $RELEASE_MAJOR | ||
echo $RELEASE_MINOR | ||
echo $RELEASE_PATCH | ||
``` | ||
|
||
If you're not publishing to npm and only want to use this action for GitHub releases, you'd only | ||
need to provide a `GITHUB_TOKEN` env var. You'll also need to include a `.releaserc.js` file in your | ||
repo, instructing `semantic-release` to not look to publish to `npm`. | ||
If you're _not_ publishing to npm and only want to use this action for GitHub releases, you need to | ||
include a `.releaserc.js` file in your repo, instructing `semantic-release` to not publish to the | ||
`npm` registry. | ||
|
||
**Example:** | ||
Example `.releaserc.js` if you're not publishing to npm: | ||
|
||
```js | ||
module.exports = { | ||
|
@@ -73,18 +129,71 @@ module.exports = { | |
}; | ||
``` | ||
|
||
### Inputs | ||
## Why | ||
|
||
None. Might be a good idea to accept optional configuration values via inputs that would merge, yet | ||
override any `.releaserc.js` config file values. | ||
It's fairly easy to run `semantic-release` as a "host action," aka something that simply runs | ||
directly on the VM. | ||
|
||
```yml | ||
steps: | ||
- run: npx semantic-release | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
``` | ||
|
||
If you're just publishing a node package, then this could still work well for you. The problem I | ||
found with this is when I was in projects where I had subsequent steps/actions in which I wanted to | ||
know whether a new version was cut. | ||
|
||
> **Use Case:** For instance, in an application where I'm using `semantic-release` to manage GitHub | ||
> releases, but also building and pushing docker images. Dockerhub has a | ||
> [nice GitHub integration](https://docs.docker.com/docker-hub/builds/) to handle this for us, but | ||
> some other registries do not. If I need to cut a new release, then update a docker registry by | ||
> adding a new tagged build, I'll want to run `semantic-release` and then build a docker image, tag | ||
> it with a version and push it up. In my case I like to push up tags for `latest`, the semver (i.e. | ||
> `v1.8.3`), and just the major the version (i.e. `v1`). | ||
|
||
I want to know 1) if semantic-release cut a new version and 2) what the version is. | ||
|
||
There's a number of ways to handle this, but the most elegant way I found to do it was to abstract | ||
it into it's own custom action. It abstracts away whatever logic you need to figure out what that | ||
new release number is. | ||
|
||
This also scales well, just in case I want to add some flexibility and functionality to this action, | ||
I can easily leverage it across any project. | ||
|
||
## Inputs | ||
|
||
**Docs:** https://help.github.com/en/articles/metadata-syntax-for-github-actions#inputs | ||
|
||
None yet. Might be a good idea to accept optional configuration values via inputs that would merge, | ||
yet override any `.releaserc.js` config file values. i.e. `branch`, etc. | ||
|
||
### Outputs | ||
|
||
`semantic-release-action` sets both output variables and environment variables because why not? | ||
Allows users the ability to use whichever they want. I don't know or understand every use case there | ||
might be so this is a way to cover more cases. | ||
|
||
**Docs:** https://help.github.com/en/articles/metadata-syntax-for-github-actions#outputs | ||
|
||
**Output Variables**: | ||
|
||
| Output Variable | Description | | ||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| new-release-published | Either `'true'` when a new release was published or `'false'` when no release was published. Allows other actions to run or not-run based on this | | ||
| release-version | The new releases' semantic version, i.e. `1.8.3` | | ||
| release-major | The new releases' major version number, i.e. `1` | | ||
| release-minor | The new releases' minor version number, i.e. `8` | | ||
| release-patch | The new releases' patch version number, i.e. `3` | | ||
|
||
**Environment Variables**: | ||
|
||
- `SEMANTIC_RELEASE`: Either `'true'` or `'false'`. This allows other actions to run or not-run | ||
based on this. | ||
- `SEMANTIC_RELEASE_VERSION`: The new release's semantic version, i.e. `1.8.3`. | ||
- `SEMANTIC_RELEASE_MAJOR`: The new release's major version number, i.e. `1`. | ||
- `SEMANTIC_RELEASE_MINOR`: The new release's minor version number, i.e. `8`. | ||
- `SEMANTIC_RELEASE_PATCH`: The new release's patch version number, i.e. `3`. | ||
| Environment Variable | Description | | ||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| NEW_RELEASE_PUBLISHED | Either `'true'` when a new release was published or `'false'` when no release was published. Allows other actions to run or not-run based on this | | ||
| RELEASE_VERSION | The new releases' semantic version, i.e. `1.8.3` | | ||
| RELEASE_MAJOR | The new releases' major version number, i.e. `1` | | ||
| RELEASE_MINOR | The new releases' minor version number, i.e. `8` | | ||
| RELEASE_PATCH | The new releases' patch version number, i.e. `3` | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,45 @@ | ||
const core = require('@actions/core'); | ||
const semanticRelease = require('semantic-release'); | ||
|
||
async function main() { | ||
try { | ||
const result = await semanticRelease(); | ||
|
||
if (result) { | ||
const { lastRelease, nextRelease, commits } = result; | ||
|
||
core.debug( | ||
`Published ${nextRelease.type} release version ${nextRelease.version} containing ${commits.length} commits.`, | ||
); | ||
|
||
if (lastRelease.version) { | ||
core.debug(`The last release was "${lastRelease.version}".`); | ||
} | ||
|
||
// outputs | ||
const { version } = nextRelease; | ||
const major = version.split('.')[0]; | ||
const minor = version.split('.')[1]; | ||
const patch = version.split('.')[2]; | ||
|
||
core.exportVariable('SEMANTIC_RELEASE', true); | ||
core.exportVariable('SEMANTIC_RELEASE_VERSION', version); | ||
core.exportVariable('SEMANTIC_RELEASE_MAJOR', major); | ||
core.exportVariable('SEMANTIC_RELEASE_MINOR', minor); | ||
core.exportVariable('SEMANTIC_RELEASE_PATCH', patch); | ||
|
||
// TODO: core.setOutput as well? What are outputs, how do they differ from env vars? | ||
} else { | ||
core.exportVariable('SEMANTIC_RELEASE', false); | ||
core.debug('No release published'); | ||
} | ||
} catch (err) { | ||
core.setFailed(`Action failed with error ${err}`); | ||
async function run() { | ||
const result = await semanticRelease(); | ||
|
||
if (!result) { | ||
core.debug('No release published'); | ||
|
||
// set outputs | ||
core.exportVariable('NEW_RELEASE_PUBLISHED', 'false'); | ||
core.setOutput('new-release-published', 'false'); | ||
return; | ||
} | ||
|
||
const { lastRelease, nextRelease, commits } = result; | ||
|
||
core.debug( | ||
`Published ${nextRelease.type} release version ${nextRelease.version} containing ${commits.length} commits.`, | ||
); | ||
|
||
if (lastRelease.version) { | ||
core.debug(`The last release was "${lastRelease.version}".`); | ||
} | ||
|
||
// outputs | ||
const { version } = nextRelease; | ||
const major = version.split('.')[0]; | ||
const minor = version.split('.')[1]; | ||
const patch = version.split('.')[2]; | ||
|
||
// set outputs | ||
core.exportVariable('NEW_RELEASE_PUBLISHED', 'true'); | ||
core.exportVariable('RELEASE_VERSION', version); | ||
core.exportVariable('RELEASE_MAJOR', major); | ||
core.exportVariable('RELEASE_MINOR', minor); | ||
core.exportVariable('RELEASE_PATCH', patch); | ||
core.setOutput('new-release-published', 'true'); | ||
core.setOutput('release-version', version); | ||
core.setOutput('release-major', major); | ||
core.setOutput('release-minor', minor); | ||
core.setOutput('release-patch', patch); | ||
} | ||
|
||
main(); | ||
run().catch(core.setFailed); |