I would like to use a pure solution in a GitHub action to increment a version of the package. I don't want to use any existing actions from the GitHub marketplace such as "gh-action-bump-version
". I have this workflow, which will increase the version and create a tag.
name: Version Increment
on:
push:
branches:
- main
tags-ignore:
- v*
jobs:
version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
with:
token: ${{ secrets.ACCESS_TOKEN }}
- run: git config user.email "$GITHUB_ACTOR#users.noreply.github.com"
- run: git config user.name "$GITHUB_ACTOR"
- run: npm version minor -m "v%s"
- run: VERSION=$(node -p "require('./package.json').version")
- run: git tag ${VERSION}
- run: git push origin --tags
- run: git push origin --follow-tags
It works, but it also cause a circular runs of the actions because of the last row. I know that I can use a custom message like "[RELEASE]" and put there a "if" condition and skip these commits. But my question is, is there any better solution to skip these commits from this action and do not use the "if" condition? Because the "tags-ignore" obviously doesn't work.
So I found several solutions. The first is that you can put "[skip actions]" to your commit message and that commit will skip any github action that should run within the commit. The second one is to use an address of the repository with access token.
This works pretty well for me:
name: Version Increment
on:
push:
branches:
- main
jobs:
version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- run: git config user.email "$GITHUB_ACTOR#users.noreply.github.com"
- run: git config user.name "$GITHUB_ACTOR"
- run: npm version minor -m "v%s"
- run: VERSION=$(node -p "require('./package.json').version")
- run: git tag ${VERSION}
- run: git push "https://$GITHUB_ACTOR:${{ secrets.ACCESS_TOKEN }}#github.com/$GITHUB_REPOSITORY.git" --follow-tags
- run: git push "https://$GITHUB_ACTOR:${{ secrets.ACCESS_TOKEN }}#github.com/$GITHUB_REPOSITORY.git" --tags
Try using the built in GITHUB_TOKEN instead of your custom ACCESS_TOKEN. That should prevent the workflow from triggering another workflow.
From the docs (https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow):
When you use the repository's GITHUB_TOKEN to perform tasks, events triggered by the GITHUB_TOKEN will not create a new workflow run. This prevents you from accidentally creating recursive workflow runs. For example, if a workflow run pushes code using the repository's GITHUB_TOKEN, a new workflow will not run even when the repository contains a workflow configured to run when push events occur.
Related
This question already has an answer here:
GitHub Actions auto-approve not working on pull request created by GitHub Actions bot
(1 answer)
Closed 7 months ago.
I implemented a workflow that runs once a week and updates all the project dependencies and opens a PR with its changes using the workflow token.
name: Automatic dependency update
"on":
workflow_dispatch: null
schedule:
- cron: 0 0 * * 1
jobs:
update:
name: Update to latest versions
runs-on:
- self-hosted
- default-runner
steps:
- name: Checkout Project
uses: actions/checkout#v2
- name: Install Java
uses: actions/setup-java#v2
- name: Update Versions
run: |
./gradlew useLatestVersions --info
- name: Commit and open PR
uses: peter-evans/create-pull-request#v3
with:
commit-message: Update to latest versions
committer: Update Bot <workflow#xxx.com>
branch: auto-dependency-update
base: dev
delete-branch: true
title: Automatic dependency update
draft: false
team-reviewers: XX/teamname
body: Automated gradle dependency updates
The issue is, that for this PR the normal workflows (that are mandatory for the PR merge are not triggered.
name: Build pipeline
"on":
workflow_dispatch: null
pull_request:
branches:
- dev
push:
branches:
- '!master'
- '**'
defaults:
run:
shell: bash
jobs:
build:
name: Compile
runs-on:
- self-hosted
- default-runner
steps:
- name: Checkout code
uses: actions/checkout#v2
- uses: actions/setup-java#v2
- name: Compile code
run: |
./gradlew classes testClasses --info
# ...
When I manually push something to that branch, the workflows are triggered. Though when I add the following step to the version update workflow, then the workflows aren't triggered either.
So what can I do? I dont want to trigger the workflows explicityl (e.g. using benc-uk/workflow-dispatch#v1) to keep the update mechanism as generic as possible.
According to the official documentation
When you use the repository's GITHUB_TOKEN to perform tasks, events triggered by the GITHUB_TOKEN will not create a new workflow run.
This prevents you from accidentally creating recursive workflow runs. For example, if a workflow run pushes code using the repository's GITHUB_TOKEN, a new workflow will not run even when the repository contains a workflow configured to run when push events occur.
For more information, see "Authenticating with the GITHUB_TOKEN."
The action you're using to open the PR also states in the Inputs section that you can change the GITHUB_TOKEN scope as well, or use a PAT:
GITHUB_TOKEN (permissions contents: write and pull-requests: write) or a repo scoped Personal Access Token (PAT).
Solution
Therefore, you just need to add a token input to the peter-evans/create-pull-request action using a secret allowing you to trigger a workflow from another workflow.
I'm trying to build a repository which allows me to build Docker images for different versions of a project I'm forking.
The repo should have the following layout:
main branch where the workflow is defined, with a trigger such as:
on:
push:
branches-ignore:
- main
The workflow builds the software from any branch (basically a mvn clean package, docker build and docker push that applies to all versions of the software)
many software-1.2.3 branches which don't contain any .github/workflow files (it would be cumbersome to copy this file into each branch, and maintain it there)
From my research so far, it seems that GitHub Actions only runs when a workflow definition is present. However, I wonder if there's a way using webhooks or something to trick the system into doing what I want.
My next best option would probably be using workflow_dispatch,
on: push !main wouldn't work, because that !main branch would need to have this workflow in it.
Running the workflow manually is the easiest solution to implement.
on:
workflow_dispatch:
inputs:
BRANCH_OF_FORK:
description: 'branch name, on which this pipeline should run'
required: true
jobs:
doSomething:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
ref: ${{ github.event.inputs.BRANCH_OF_FORK }}
- run: docker build something something
There's a on:fork event, that could be used to trigger a run, but it could only trigger a fork event of this specific branch, that has the on:fork code in it's workflow.
It's possible to run the workflow on a cron job without on-fork event, but you would have to pick the correct branch programmatically.
steps:
- id: branch-selector
run: |
git clone ${{ github.event.repo.url }} .
all_branches=`git branch --all | grep -v " main\$" | grep -v "/main\$"`
correct_branch=`pick_correct_branch.py $all_branches`
git checkout -b $correct_branch
- run: docker build something something
pick_correct_branch.py is left as an exercise for the reader to implement.
I'm setting up Github action to lint the OpenAPI Spec using Spectral. Before linting, I would like to generate the single file spec and commit it.
I have set up a workflow that will first build and then lint. But the problem is, the lint is not considering the commit made by Github action in the previous step. It always lint for the commit that triggered this action. Is there any way to lint with the commit made as part of Github action?
You can see from the above image that Github workflow didn't run for the commit made by Github action.
Workflow file:
name: Run Spectral
on:
- pull_request
jobs:
build:
name: Build Spec
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout#v2
- name: Set up Node.js
uses: actions/setup-node#v1
with:
node-version: 12.x
- name: Install dependencies
run: npm install
- name: Build spec file
run: npm run build
- name: Commit build changes
uses: EndBug/add-and-commit#v7
with:
default_author: github_actions
message: 'Compiled spec file'
add: '_build/oas.yaml'
lint:
name: Lint
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout Repository
uses: actions/checkout#v2
- name: Spectral Linting
uses: stoplightio/spectral-action#v0.7.3
with:
file_glob: '_build/oas.yaml'
That's because commits made using the standard GITHUB_TOKEN aren't triggering workflows; you have to use a personal access token for an automated workflow that's supposed to kick off another workflow.
Quoting from the docs (linked above):
When you use the repository's GITHUB_TOKEN to perform tasks on behalf of the GitHub Actions app, events triggered by the GITHUB_TOKEN will not create a new workflow run. This prevents you from accidentally creating recursive workflow runs. [...]
If you would like to trigger a workflow from a workflow run, you can trigger the event using a personal access token. [...]
I'm currently testing Github Actions workflows on this repository.
Context
I'm trying to use this workflow (1st):
on:
workflow_dispatch:
jobs:
job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- run: |
date > report.txt
git config user.name github-actions
git config user.email github-actions#github.com
git add .
git commit -m "generate or update report.txt file"
git push
To trigger this workflow (2nd):
on:
push:
paths:
- '**/report.txt'
pull_request:
paths:
- '**/report.txt'
jobs:
job:
runs-on: ubuntu-latest
steps:
- run: echo "Report .txt file has been updated"
What I tried
I followed the Github Action Documentation to implement the 2nd workflow with a Filter Pattern.
When I update the report.txt file locally, then commit and push the code to the repository, the 2nd workflow triggers.
However, I don't understand why the 2nd workflow doesn't trigger when the 1st workflow is completed, even with the report.txt file being updated on the default branch.
EDIT: I know I could trigger the 2nd workflow using others trigger event types (examples: repository_dispatch or workflow_run). But I'm trying to do it from a git push command on another workflow.
Question
Did I miss something on the 1st workflow to make it trigger the 2nd, or should I add something on the 2nd workflow to make it being triggered by the 1st one?
No, you didn't miss anything in your workflows.
You just need a different token.
When you use actions/checkout, it uses the GITHUB_TOKEN for authentication, and according to the documentation it doesn't trigger a new workflow run:
When you use the repository's GITHUB_TOKEN to perform tasks on behalf
of the GitHub Actions app, events triggered by the GITHUB_TOKEN will
not create a new workflow run. This prevents you from accidentally
creating recursive workflow runs.
To make it work, you need to generate a PAT (Personal Access Token), store it in your repository secrets, and use it in your checkout step:
- uses: actions/checkout#v2
with:
token: ${{ secrets.YOUR_PAT_TOKEN }}
There are three ways of authentication within a GitHub action.
1. GITHUB_TOKEN
The GITHUB_TOKEN is always available and implicitly defined by GitHub.
- uses: actions/checkout#v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
It has limited permissions, though, as it cannot trigger new workflow runs. This is why your second workflow does not start.
2. PAT (Personal Access Token)
A personal access token can be generated in your developer settings. You can then add it as an encryped secret, e.g. PAT_TOKEN to the GitHub project and use it instead of the GITHUB_TOKEN:
- uses: actions/checkout#v3
with:
token: ${{ secrets.PAT_TOKEN }}
Subsequent push actions in the same workflow will then trigger any configured GitHub workflow as if they were pushed manually.
Be aware that the personal access token has access to all of your repositories and hence can be a potential security risk.
3. Deploy key
You can generate a dedicated SSH keypair and add it to the repository as a Deploy Key. This is an alternative to the token-based authentication and has the same effect as the personal access token, but it only provides access to a single repository. It is done as follows:
Generate an SSH keypair:
ssh-keygen -N "" -f deploy_key -C "github-actions"
Add the private key (generated file deploy_key) as an encryped secret, e.g. COMMIT_KEY to the GitHub project.
Add the public key (generated file deploy_key.pub) as a deploy key with write access to the GitHub project. Tick the Allow write access checkbox.
When checking out the source code in your workflow, add the SSH key:
- uses: actions/checkout#v3
with:
ssh-key: "${{secrets.COMMIT_KEY}}"
Can I trigger a new workflow from another workflow?
I'm trying to run a workflow after the first workflow has pushed a new release and it seems to ignore it.
Found the answer here:
An action in a workflow run can't trigger a new workflow run. For example, if an action pushes code using the repository's GITHUB_TOKEN, a new workflow will not run even when the repository contains a workflow configured to run when push events occur.
EDIT:
The quote above might be confusing. When I add a Personal Access Token (PAT) to the checkout action with repo permissions granted (and not repository's GITHUB_TOKEN), the following commands DO trigger other workflows:
- name: Checkout Repo
uses: actions/checkout#v2
with:
token: ${{ secrets.PAT_TOKEN }}
(In my case, running semnatic-release after this checkout, which creates a new release with a new tag - did trigger another workflow that runs only if a tag was created)
As described here, you can trigger another workflow using the workflow_run event.
For example we could think of two workflow definitions like this (the only prerequisite is, that both reside in the same repository - but I'am sure, there's also an event for other repos as well):
release.yml
name: CI release
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Release artifact
run: ...
do-something-different.yml
name: Do anything after the release of the first workflow
on:
workflow_run:
workflows: ["CI release"]
types:
- completed
jobs:
notify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Do something
run: ...
A crucial point here is that the name: CI release definition of the first yaml file must exactly match the workflow_run: workflows: ["CI release"] definition in the second yaml file. Another point is that this approach needs to be done on the default branch (which is mostly main or master) as the docs state:
Note: This event will only trigger a workflow run if the workflow file
is on the default branch.
If you don't want to use a general Personal Access Token (which has access to all of your repos), you can generate a dedicated SSH keypair for this purpose and add it to the repository as a Deploy Key. This is done as follows:
Generate an SSH keypair:
ssh-keygen -N "" -f deploy_key -C "github-actions"
Add the private key (generated file deploy_key) as an encryped secret, e.g. COMMIT_KEY to the GitHub project.
Add the public key (generated file deploy_key.pub) as a deploy key with write access to the GitHub project. Tick the Allow write access checkbox.
When checking out the source code in your workflow, add the SSH key:
- name: Checkout
uses: actions/checkout#v3
with:
ssh-key: "${{secrets.COMMIT_KEY}}"
Subsequent push actions in the same workflow will then trigger any configured GitHub workflow as if they were pushed manually.