How can I cancel a GitHub Actions workflow if the commit has no tag - github

I have npm publish github actions, I want to run this action if my commit has tag, otherwise I don't want to run my action because of that if I do not add any tag my commit then action is run and failed because it try to publish already publish npm package with same tag. For example with my last commit I have tag 1.2.3 and my npm package was publish with 1.2.3 version. When I add new commit to my branch without any tag actions try to publish my package with 1.2.3 version tag so it failed. Here my actions code below, is there any solution for it.
Thanks for advive.
name: NPM Publish
on:
push:
branches:
- master
tags:
- v*
jobs:
build:
name: Build 🏗 & Publish 🚀
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v1
- uses: actions/setup-node#v2.4.0
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm install
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
I need something like that on yml file
if(git_commit has tag) continue job else stop job;
EDITTED VERSION
I edit my yml file base on #Enrico Campidoglio suggestion but still is does not work. I made two commit first one without tag and it canceled the action but second one has tag it still canceled action. Is there any new suggestion or solution ?
name: NPM Publish
on:
push:
branches:
- master
jobs:
build:
name: Build 🏗 & Publish 🚀
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v1
- uses: actions/setup-node#v2.4.0
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: echo "GIT_COMMIT=`echo $(git rev-parse --short HEAD)`" >> $GITHUB_ENV
- run: echo "GIT_TAG=`echo $(git describe --tags --exact-match ${{ env.GIT_COMMIT }} || :)`" >> $GITHUB_ENV
- run: echo ${{ env.GIT_TAG }} != v*
- run: |
if [[ ${{ env.GIT_TAG }} == v* ]] ; then
echo "Tag found..."
else
echo "No git tag found, action cancelled..."
exit 1
fi
- uses: andymckay/cancel-action#0.2
if: ${{ env.GIT_TAG }} != v*
- run: npm install
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
there is action result I cannot figure out what is the problem,
here the lastest failed action: https://github.com/sametcelikbicak/enum2array/runs/3513521031?check_suite_focus=true

I found the solution finally after too many tried. I changed my mind and try to run shell script and it works :)
Just add that line in my yml file
- name: Check Git Tag to continue publish
run: ./scripts/publish.sh
and I created a sh file for control the commit tag. You can find the latest script and yml file definitions below
Here is my lastest yml file, npm-publish.yml
name: NPM Publish
on:
push:
branches:
- master
jobs:
build:
name: Build 🏗 & Publish 🚀
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v1
- uses: actions/setup-node#v2.4.0
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- name: Check Git Tag to continue publish
run: ./scripts/publish.sh
- run: npm install
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
Here is my script file, publish.sh
#!/usr/bin/env bash
GIT_COMMIT=$(git rev-parse --short HEAD)
GIT_TAG=$(git describe --tags --exact-match $COMMIT || :)
if [[ ${GIT_TAG} == v* ]] ; then
echo "$GIT_TAG Tag found..."
else
echo "No git tag found, action cancelled..."
exit 1
fi

For the time being, there isn't an official action to cancel the current workflow. There is, however, an official GitHub API and a third-party action that invokes it. You could combine it with an if conditional and the github context to achieve what you want:
steps:
- uses: andymckay/cancel-action#0.2
if: startsWith(github.ref, 'refs/tags')
Be aware that cancelling a workflow through the API is an asynchronous operation, which means that later steps might still get executed until the workflow runner handles the request.
A much more solid approach would be to put a condition on your publishing step to only run when the workflow was triggered by a new tag:
steps:
- run: npm publish --access public
if: startsWith(github.ref, 'refs/tags')
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

Related

Releasing and Publishing via GH actions

I am trying to automate publishing the SDKs for Python, Java, GO, and Node. My main goal is to make the CI run whenever a new PR is created against main branch that will:
bump the version in all files.
publish the new release to the related public registry (for each language)
Problem:
right now the problem is that the publish step is not taking the artifacts from the release step, but rather the one before that, as if they are not synced.
For the release step, we're using semantic-release package with several plugins.
The ADMIN_TOKEN is a personal token of a user with write permissions.
The publishing step is different for each language, but I am certain this is unrelated since it worked before I complicated the workflow.
Possible issue:
Without the if statements, the release and publish steps are synced, but then the semantic-release creates another commit that creates another release (e.g. 2 releases and publishing in one run, not wanted). With the current if, the publish step takes the older release instead the newly created one (for example, if the new run creates release 1.0.40, the publish will take version 1.0.39).
Does anyone have some input on these 2 steps or the if statements? For example, this is the current variation of the Java workflow:
release:
runs-on: ubuntu-latest
if: "!startsWith(github.event.head_commit.message, 'chore')"
steps:
- name: Checkout code
uses: actions/checkout#v3
with:
fetch-depth: 0
token: ${{ secrets.ADMIN_TOKEN }}
- name: setup nodejs
uses: actions/setup-node#v3
with:
node-version: '16'
- name: release using semantic-release
env:
GITHUB_TOKEN: ${{ secrets.ADMIN_TOKEN }}
GIT_AUTHOR_NAME: ****
GIT_AUTHOR_EMAIL: ****
GIT_COMMITTER_NAME: ****
GIT_COMMITTER_EMAIL: ****
run: |
sudo apt-get update
sudo apt-get install python
pip install --user bumpversion
npm install #semantic-release/changelog
npm install #semantic-release/exec
npm install #semantic-release/git
npm install #semantic-release/github
npx semantic-release
publish:
runs-on: ubuntu-latest
needs: [release]
if: "!startsWith(github.event.head_commit.message, 'chore')"
steps:
- name: Checkout code
uses: actions/checkout#v3
with:
token: ${{ secrets.ADMIN_TOKEN }}
- name: Configure GPG Key
run: |
cat <(echo -e "${{ secrets.GPG_SIGNING_KEY }}") | gpg --batch --import
gpg --list-secret-keys --keyid-format LONG
- name: Set up Maven Central Repository
uses: actions/setup-java#v3
with:
java-version: 8
distribution: zulu
server-id: ossrh
server-username: ${{ secrets.MAVEN_USERNAME }}
server-password: ${{ secrets.MAVEN_PASSWORD }}
gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
- name: Publish package
run: mvn clean deploy $MVN_ARGS -P central --no-transfer-progress --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }}
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
MVN_ARGS: "--settings build-settings.xml"
<more ENVS>
In case it is relevant, the .releaserc file is:
{
"debug": true,
"branches": [ "main" ],
"plugins": [
["#semantic-release/commit-analyzer", {
"preset": "angular",
"releaseRules": [
{"type": "release","release": "patch"}
]}],
"#semantic-release/release-notes-generator",
"#semantic-release/changelog",
[
"#semantic-release/exec",
{
"prepareCmd": "bump2version --allow-dirty --current-version ${lastRelease.version} --new-version ${nextRelease.version} patch"
}
],
[
"#semantic-release/git",
{
"message": "chore(release): ${nextRelease.version} release notes\n\n${nextRelease.notes}"
}
],
"#semantic-release/github"
]
}
I also asked in GH: https://github.com/orgs/community/discussions/40749
The quick fix I found is to split the release and publish steps into two different workflows (different files). I am certain with a bit more dive-in, one can merge those two with some proper if conditioning.
NOTE: The publish action steps are specific to Java, but can be changed to be valid for any other language. The main structure is the main answer here.
The release step:
The semantic-release creates a secondary commit to the main branch with "chore" commit message. in order to overcome this, I added the if to skip this type of commit.
name: release
on:
workflow_dispatch:
push:
branches:
- main
jobs:
release:
runs-on: ubuntu-latest
if: "github.event_name == 'push' && github.ref == 'refs/heads/main' && !startsWith(github.event.head_commit.message, 'chore')"
steps:
- name: Checkout code
uses: actions/checkout#v3
with:
fetch-depth: 0
token: ${{ secrets.ADMIN_TOKEN }}
- name: setup nodejs
uses: actions/setup-node#v3
with:
node-version: '16'
- name: release using semantic-release
env:
GITHUB_TOKEN: ${{ secrets.ADMIN_TOKEN }}
GIT_AUTHOR_NAME: secrets.automation.dev
GIT_AUTHOR_EMAIL: secrets.automation.dev#il.ibm.com
GIT_COMMITTER_NAME: secrets.automation.dev
GIT_COMMITTER_EMAIL: secrets.automation.dev#il.ibm.com
run: |
sudo apt-get update
sudo apt-get install python
pip install --user bumpversion
npm install #semantic-release/changelog
npm install #semantic-release/exec
npm install #semantic-release/git
npm install #semantic-release/github
npx semantic-release
The publish step:
The "release" event has several initiators so I added the published type to make sure the publishing happens only if a new release was published to GitHub.
name: publish artifact
on:
workflow_dispatch:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout#v3
with:
token: ${{ secrets.ADMIN_TOKEN }}
- name: Configure GPG Key
run: |
cat <(echo -e "${{ secrets.GPG_SIGNING_KEY }}") | gpg --batch --import
gpg --list-secret-keys --keyid-format LONG
- name: Set up Maven Central Repository
uses: actions/setup-java#v3
with:
java-version: 8
distribution: zulu
server-id: ossrh
server-username: ${{ secrets.MAVEN_USERNAME }}
server-password: ${{ secrets.MAVEN_PASSWORD }}
gpg-passphrase: ${{ secrets.GPG_PASSPHRASE }}
- name: Publish package
run: mvn clean deploy $MVN_ARGS -P central --no-transfer-progress --batch-mode -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }}
env:
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
MVN_ARGS: "--settings build-settings.xml"
<other envs>

Conditional job execution for Github actions

I would like to conditionally execute a Github Action according to a previous job (Format).
If the code needed to be formatted, I would like to execute the following job (create_commit), otherwise skip it and do nothing.
Unfortunately at the moment the second job never gets triggered, no matter what is the output of the first job.
My action:
name: Format
on: push
jobs:
format:
name: Code formatting in Black
runs-on: ubuntu-latest
outputs:
trigger_commit: ${{ steps.changes_present.outputs.changes_detected }}
steps:
- name: Checkout repository
uses: actions/checkout#v3
- name: Install package
run: pip install 'black[d]'
- name: Run black formatter
run: black .
- name: Check diff for changes
id: changes_present
run: |
outputs=$(git diff)
if ! [ -z "$outputs" ]
then
echo '::set-output name=changes_detected::true'
fi
create_commit:
runs-on: ubuntu-latest <- Job never executed
needs: format
if: needs.format.outputs.changes_detected == true
steps:
- name: Commit
run: |
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]#users.noreply.github.com'
git commit -am "Files updated after formatting"
git push
The output of the format job is named trigger_commit instead of changes_detected. So try this:
if: needs.format.outputs.trigger_commit == `true`
You could use the actionlint to check this error, an online version is available too. See this link .

How to use github-secret in github action workflow?

so I have this code:
name: run-script
on: push
jobs:
run_tests:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout#v2
- name: Run script file
run: |
echo {here should be the secret} > ~/id_rsa
shell: bash
On my git action, where {here should be the secret} I want to put the variable, which is a secret token saved as a repo secret.
How can this be done?
Thank you for your help.
Assuming you have a secret named TOKEN, you can use it like so:
name: run-script
on: push
jobs:
run_tests:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout#v3
- name: Run script file
run: |
echo ${{ secrets.TOKEN }} > ~/id_rsa
shell: bash
Unrelated to how to use secrets, please note that > will override the contents of ~/id_rsa.
Secondly, if you want to do something with your private key (which is my guess based on the filename), the correct file would be in ~/.ssh/id_rsa.
And lastly, note that I have changed the checkout action to v3 as that's the latest available version.

How to setup eslint to lint everything between master branch and HEAD

I'm trying to setup GitHub action to check for lint errors and fail the pull request if any error/ warnings detected.
Currently my logic works locally but when I try to run it via GitHub action, I get an error:
fatal: ambiguous argument 'origin/master...HEAD': unknown revision or
path not in the working tree.
I believe it's something to do with checkout#v2 not fetching the right amount of data, But I cant get my head around what
Code Sample
name: Initiate PR
on: push
jobs:
STEPS:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout#v2
with:
fetch-depth: 100
- name: Set up Node.js
uses: actions/setup-node#v1
with:
node-version: 14.18.0
- name: Install Node.js dependencies
run: npm ci --ignore-scripts
- name: lint-on-PR
shell: bash
run: |
npx eslint --max-warnings 0 $(git diff origin/master...HEAD --name-only --relative --diff-filter=MATR '***.js' '***.jsx' '***.ts' '***.tsx' | xargs)
You would probably need to do a checkout#v1 as in this example to get all the files.
- uses: actions/checkout#v1
...
- run: git diff ${{ github.event.pull_request.base.sha }} ${{ github.sha }}
v2 by default only fetches the sha that triggered the action.

GitHub Action - Unable to add "if" condition in steps

I'm using composite GitHub actions, where I want to check the current branch name in composite action's some steps and make the decision on that condition.
e.g.
name: main
on:
push:
repository_dispatch:
types:
- manual-trigger
jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout project
uses: actions/checkout#v2
- name: Fetch full project
run: git fetch --prune --unshallow
- name: Restore packages
run: nuget restore -ConfigFile "../Build/Nuget.config"
working-directory: Projects
env:
# ARTIFACTORY_PASSWORD is read by the nuget.config credentials section
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- name: Composite Action - To build solution and execute SonarScanner
uses: ./Build/build-and-sonarscanner-execution
Where in Composite action - I do have a check that Sonar-Scanner should execute only for develop branch, else only project build will gets execute.
name: build-and-sonarscanner-execution
description: "Build the solution using msbuild and SonarScanner execution"
inputs:
# Set of parameters
runs:
using: "composite"
steps:
- name: Restore packages
run: nuget restore -ConfigFile "../Build/Nuget.config"
working-directory: ${{ inputs.solution-directory }}
env:
# ARTIFACTORY_PASSWORD is read by the nuget.config credentials section
ARTIFACTORY_PASSWORD: ${{ inputs.artifactory-password }}
shell: pwsh
- name: Install dotnet-sonarscanner package
if: {{ github.ref == 'ref/head/develop' }} This is the line where it is throwing syntax error as 'if' is not allowed under steps
run: dotnet tool install --global dotnet-sonarscanner --version 4.10.0
shell: pwsh
Here and here are the references I have looked for before applying this if condition here. And that works totally fine if I apply that main.yml, but in composite action yaml file that's not working.
Can someone please share that what am I missing in here?
The above syntax if: ${{ ... }} should be fine but it seems that the composite actions do not support conditions yet: https://github.com/actions/runner/blob/main/docs/adrs/0549-composite-run-steps.md
The workaround that Benjamin proposed is working for me:
run: |
if [[ "${{inputs.myVar}}" != "" ]]; then
aws ...
fi
exit 0
shell: bash
Try the below syntax:
if: ${{ github.ref == 'refs/heads/xxxx' }}