Github Actions: Running a workflow on non-draft PRs - yaml

I have workflow file that I want it to run on non-draft PRs and on every new commit to the PR.
So far, I have tried two ways:
Using if statement
name: Test
on:
pull_request:
branches:
- master
jobs:
test:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
This does not trigger workflow when PR converted to ready for review.
Using types statement
name: Test
on:
pull_request:
branches:
- master
types:
- ready_for_review
jobs:
test:
runs-on: ubuntu-latest
This does not trigger workflow when a new commit pushed to PR.
How can I add a condition so that my workflow runs on non-draft PRs and also all new commits?

This is similar to another question.
The answer in the other question suggests using
if: ! github.event.pull_request.draft
to check if the PR is a draft, since there might otherwise be some type confusion with booleans in GitHub Actions.

In your first code block you leave the types as the default (opened, synchronize & reopened).
In the second code block you only use the ready_for_review type.
You can just combine the two:
name: Test
on:
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
jobs:
test:
if: github.event.pull_request.draft == false
# You could have ths version too - note the single quotes:
# if: '! github.event.pull_request.draft'
name: Check PR is not a Draft
runs-on: ubuntu-latest
steps:
- run: |
echo "Non-draft Pull request change detected"

Related

CircleCI filter branch by prefix

I am making a CICD pipeline with circle-ci-terraform
My dev branch names are dev/feature_name etc. Instead of running workflows by directly writing the branch name I want to use the prefix dev/ so that the same workflow runs for all branches starting with dev. Any idea how I can achieve that?
Here's my current workflow -
workflows:
dev_workflow:
jobs:
- build:
filters:
branches:
only:
- dev/cicd-integration
I already tried dev/*, it does not work.
CircleCI uses the Java variant of RegEx pattern matching (https://circleci.com/docs/workflows/#using-regular-expressions-to-filter-tags-and-branches).
So in your case, you need to specify the following RegEx pattern:
filters:
branches:
only:
- /^dev\/.*/

How can I avoid running a Github Actions Job on a pull-request

I have a GitHub action workflow that tests, builds and deploys. Quite common.
I want the job test to run on both main and PRs (into main). But I want the build and deploy to only run on pushes to main. How can I safely protect this?
The summarized .github/workflows/ci.yml looks like:
name: CI
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: "Lint, Test and Report"
run: echo "running linter, then tests then report on this"
build:
needs: test
runs-on: ubuntu-latest
steps:
- name: "Build"
run: echo "Building the artifacts"
deploy:
needs:
- test
- build
runs-on: ubuntu-latest
steps:
- name: "Deploy to Production"
run: echo "Drumroll...."
I don't see any ENV variable or github.x attribute that indicates that this is a PR. Maybe I'm missing something obvious?
Is it safe to match on branch-name instead? And e.g. use a
if: startsWith(github.ref, 'refs/heads/main')
to ensure we only ever run when the branch is main?
Yes, this is safe. However, change it to:
if: github.ref == 'refs/heads/main'
because otherwise somebody could push a branch mainfoo and you'd trigger the job as well.
An alternative would be to check for the event name, like:
if: github.event.name == 'push'
however I'd say this is less robust, since somebody could change the trigger above and remove the branches: .. part of the push trigger and suddenly you're deploying from PRs.

How to use dawidd6/action-download-artifact with pull_request trigger

This is a question for the github workflow action dawidd6/action-download-artifact.
There is no discussion board in https://github.com/dawidd6/action-download-artifact, so asking this question in this forum.
This is how I wish to use this workflow in my GitHub repo:
A pull request is created.
This triggers an workflow – lets call it the “build workflow” - to build the entire repo and uploads the build artifacts.
Then another workflow – lets call it the “test workflow” - should start, that should download the build artifact using action-download-artifact and run some other actions.
Now if I put the trigger for the “test workflow” as pull_request, then how can I make it wait for the corresponding “build workflow” to complete? Do I specify the run_id ?
For now I am using “workflow_run” as the trigger for the run WF. But then when a PR is created, it does not show the “test workflow” as one of the checks for the PR. Can you help me figure out the correct way of using the download-artifact action that would help for my purpose?
You could write two workflows where the first builds when the pull request is opened or edited, and the second executes the test when the pull request is closed and merged. The HEAD commit SHA could be used to identify the artifact name between the two workflows.
I'm going to reword your requirements slightly.
Build everything and upload the artifacts when a pull request is opened or edited (e.g. new commits added).
Download the artifact and test it when a pull request is closed and merged.
Here are two sample workflows that would accomplish that. You will need to create a token to share the artifacts between workflows (see secrets.GITHUB_TOKEN below).
Build.yml
name: Build
on:
pull_request:
jobs:
Build:
steps:
- name: Environment Variables
shell: bash
run: |
ARTIFACTS_SHA=$(git rev-parse HEAD)
BUILD_ARTIFACTS=BuildArtifacts_${ARTIFACTS_SHA}
echo "ARTIFACTS_DIR=$ARTIFACTS_DIR" >> $GITHUB_ENV
- name: Build
run: make
- name: Capture Artifacts
uses: actions/upload-artifact#2
with:
name: Artifacts_${{ env.ARTIFACTS_SHA }}
path: path/to/artifact/
Test.yml
name: Test
on:
pull_request:
types: [closed]
jobs:
Test:
steps:
- name: Environment Variables
shell: bash
run: |
ARTIFACTS_SHA=$(git rev-parse HEAD)
BUILD_ARTIFACTS=BuildArtifacts_${ARTIFACTS_SHA}
echo "ARTIFACTS_DIR=$ARTIFACTS_DIR" >> $GITHUB_ENV
- name: Download Artifacts
uses: dawidd6/action-download-artifact#v2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workflow: Build.yml
name: ${{ env.BUILD_ARTIFACTS }}

Taking a bash command's output and putting it into a message in yaml for GitHub actions?

I have the following Github Action workflow that is intended to read our lines of code coverage from a coverage.txt file and print the coverage as a comment.
name: Report Code Coverage
on:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- name: Use Node.js 12.x
uses: actions/setup-node#v1
with:
node-version: 12.x
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm run test:coverage
## I need help around here, as test:coverage generates a file and I need to get a value from a file
- uses: mshick/add-pr-comment#v1
with:
message: |
**{{Where I want the code coverage value to go}}**
🌏
!
repo-token: ${{ secrets.GITHUB_TOKEN }}
repo-token-user-login: 'github-actions[bot]' # The user.login for temporary GitHub tokens
allow-repeats: false # This is the default
Where I am struggling is on taking the output of the file, which I can obtain with bash using awk '/^Lines/ { print $2 }' < coverage.txt (not sure if there is a better alternative way) and inserting it into the message, which currently just says hello.
I found this article on yaml variables, but when I added some of that code to my own file, it just was not recognized any longer by GitHub actions (which is the only way I know to test yaml). Normally it would fail somewhere and give me an error, but after multiple attempts, the only thing that worked was to remove it.
It is quite possible that I am missing something obvious as I do not know yaml very well nor even what certain key words might be.
Alternatively, is it easier to just dump the contents of the file into the message? That could be acceptable as well.
You can create a step that gets the coverage to an output variable that then can be accessed by the next step.
Notice that for utilizing this method you will need to give the step and id and the set output variable a variable name so that you can access it in follow up steps within the same job.
Sample with your workflow below, but if you want to see a running demo here is the repo https://github.com/meroware/demo-coverage-set-output
- name: Run tests
run: npm run test:coverage
- name: Get coverage output
id: get_coverage
run: echo "::set-output name=coverage::$(awk '/^Lines/ { print $2 }' < test.txt)"
- uses: mshick/add-pr-comment#v1
with:
message: |
Coverage found ${{steps.get_coverage.outputs.coverage}}
🌏
!
repo-token: ${{ secrets.GITHUB_TOKEN }}
repo-token-user-login: 'github-actions[bot]' # The user.login for temporary GitHub tokens
allow-repeats: false # This is the default
I make a lot of github actions tutorials here if you're looking to grasp more on this topic. Cheers!!

How to reuse a strategy matrix across several jobs in Github workflows

I would like to avoid repeating a strategy matrix across jobs:
jobs:
build-sdk:
runs-on: macOS-latest
strategy:
fail-fast: false
matrix:
qt-version: ['5.15.1']
ios-deployment-architecture: ['arm64', 'x86_64']
ios-deployment-target: '12.0'
steps:
…
create-release:
needs: build-sdk
runs-on: macOS-latest
steps:
…
publish-sdk:
needs: [build-sdk, create-release]
runs-on: macOS-latest
strategy:
fail-fast: false
matrix: ?????
steps:
…
Is this possible (without creating a job to create the matrix as JSON itself)?
There's an action that allows uploading multiple assets to the same release from a matrix build that's triggered on push to a tag. Someone filed an issue about this specific use-case, and the action's author responded with
Assets are uploaded for the GitHub release associated with the same tag so as long as the this action is run in a workflow run for the same tag all assets should get added to the same GitHub release.
This suggests that a workflow like this would probably meet your needs:
on:
push:
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
jobs:
release:
runs-on: macOS-latest
strategy:
fail-fast: false
matrix:
qt-version: ['5.15.1']
ios-deployment-architecture: ['arm64', 'x86_64']
ios-deployment-target: '12.0'
steps:
- name: build SDK
run: ...
- name: Create Release
uses: softprops/action-gh-release#v1
with:
files: |
- "SDK_file1" # created in previous build step
- "SDK_file2"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: username/reponame
- name: publish SDK
run: ...
I've simplified what you would need to do, but I'm guessing you might be wanting to upload assets with names reflecting their applicable matrix options. For that detail, I recommend adding an explicit step in your job to create the asset's filename and add it to the job environment, somewhat similar to what I've done here:
- name: Name asset
run: |
BINARY_NAME=sdk-qt${{matrix.qt-version}}-iOS${{matrix.ios-deployment-target}}-${{matrix.ios-deployment-architecture}}
echo "BINARY_NAME=$BINARY_NAME" >> $GITHUB_ENV
Then, when your build step generates your assets, you can name them with the filename in ${{env.BINARY_NAME}}, and pass that same name to the release creation step like I've done in my asset release step here.

Resources