GitHub Actions: Use variables in matrix definition? - variables

I have the following code in a GitHub Action config:
name: Build & Tests
on:
pull_request:
env:
CARGO_TERM_COLOR: always
ZEROCOPY_MSRV: 1.61.0
ZEROCOPY_CURRENT_STABLE: 1.64.0
ZEROCOPY_CURRENT_NIGHTLY: nightly-2022-09-26
jobs:
build_test:
runs-on: ubuntu-latest
strategy:
matrix:
# See `INTERNAL.md` for an explanation of these pinned toolchain
# versions.
channel: [ ${{ env.ZEROCOPY_MSRV }}, ${{ env.ZEROCOPY_CURRENT_STABLE }}, ${{ env.ZEROCOPY_CURRENT_NIGHTLY }} ]
target: [ "i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu", "arm-unknown-linux-gnueabi", "aarch64-unknown-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "wasm32-wasi" ]
features: [ "" , "alloc,simd", "alloc,simd,simd-nightly" ]
exclude:
# Exclude any combination which uses a non-nightly toolchain but
# enables nightly features.
- channel: ${{ env.ZEROCOPY_MSRV }}
features: "alloc,simd,simd-nightly"
- channel: ${{ env.ZEROCOPY_CURRENT_STABLE }}
features: "alloc,simd,simd-nightly"
I'm getting the following parsing error on this file:
Invalid workflow file: .github/workflows/ci.yml#L19
You have an error in your yaml syntax on line 19
It appears to be referring to this line (it's actually one off, but maybe it's zero-indexing its line numbers?):
channel: [ ${{ env.ZEROCOPY_MSRV }}, ${{ env.ZEROCOPY_CURRENT_STABLE }}, ${{ env.ZEROCOPY_CURRENT_NIGHTLY }} ]
Is there any way to use variables in the matrix definition like this? Or do I just need to hard-code everything?

According to the documentation (reference 1 and reference 2)
Environment variables (at the workflow level) are available to the steps of all jobs in the workflow.
In your example, the environment variables are used at the job level (inside the job strategy / matrix definition), not inside the job steps.
At that level, environment variables aren't interpolated by the GitHub interpreter.
First alternative
Hardcode the values inside the channel field inside your matrix strategy:
Example:
channel: [ "1.61.0", "1.64.0", "nightly-2022-09-26" ]
However, you'll have to do this for each job (bad for maintenance as duplicated code).
Second alternative
Use inputs (with reusable workflow workflow_call trigger, or with workflow_dispatch trigger.
Example:
on:
workflow_dispatch: # or workflow_call
inputs:
test1:
description: "Test1"
required: false
default: "test1"
test2:
description: "Test2"
required: false
default: "test2"
test3:
description: "Test3"
required: false
default: "test3"
jobs:
build_test:
runs-on: ubuntu-latest
strategy:
matrix:
channel: [ "${{ inputs.test1 }}", "${{ inputs.test2 }}", "${{ inputs.test3 }}" ]
In that case, inputs will be interpolated by the GitHub interpreter.
However, you'll need to trigger the workflow from another workflow, or through the GitHub API to send the inputs (in some way, it gives you more flexibility with the values, but increase the complexity).

Related

Passing variable between jobs in Azure Pipeline with empty result

I am writing an azure pipeline yml requesting to pass variables between jobs but the variables are not passing through. however, it wasn't successful and it returns an empty variable.
here is my pipeline:
jobs:
- job: UpdateVersion
variables:
terraformRepo: ${{ parameters.terraformRepo }}
pool:
vmImage: ubuntu-latest
steps:
- checkout: self
persistCredentials: true
- checkout: ${{ parameters.terraformRepo }}
- task: AzureCLI#2
displayName: PerformVerUpdate
inputs:
azureSubscription: ${{ parameters.azureSubscriptionName }}
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
echo Step 3 result
echo "Reponame $Reponame"
echo "notify $notify"
echo "pullRequestId $pullRequestId"
echo "##vso[task.setvariable variable=pullRequestId;isOutput=true;]$pullRequestId"
echo "##vso[task.setvariable variable=Reponame;isOutput=true;]$Reponame"
echo "##vso[task.setvariable variable=notify;isOutput=true;]true"
Name: PerformVerUpdate
- job: SlackSuccessNotification
dependsOn: UpdateVersion
condition: and(succeeded(), eq(dependencies.UpdateVersion.outputs['PerformVerUpdate.notify'], 'true'))
pool:
vmImage: 'ubuntu-latest'
variables:
- group: platform-alerts-webhooks
- name: notify_J1
value: $[ dependencies.UpdateVersion.outputs['PerformVerUpdate.notify'] ]
- name: pullRequestId_J1
value: $[ dependencies.UpdateVersion.outputs['PerformVerUpdate.pullRequestId'] ]
- name: Reponame_J1
value: $[ dependencies.UpdateVersion.outputs['PerformVerUpdate.Reponame'] ]
steps:
- task: AzurePowerShell#5
displayName: Slack Notification
inputs:
pwsh: true
azureSubscription: ${{ parameters.azureSubscriptionName }}
ScriptType: 'InlineScript'
TargetAzurePs: LatestVersion
inline: |
write-host "Reponame $(Reponame_J1)"
write-host "pullRequest $(pullRequestId_J1)"
I've tried so many different syntax for it but the variables are still not able to pass through between both jobs - e.g. The condition is passing Null result to second job "(Expanded: and(True, eq(Null, 'true'))". Could anyone help with this?
Firstly 'Name' should be 'name' in lowercase
Name: PerformVerUpdate
The rest of syntax seems fine(I have tested it on Bash task because I do not have Azure subscription).
If renaming 'Name' does not help I suppose the problem may be that your Bash task is running within AzureCLI#2 task.
Maybe as workaround you could add new Bash task right after AzureCLI#2 and try to set there output variable for next job?

azure devops yaml 'if' not evaluating as expected

Oh man, I'm having a really time with the yaml learning curve. Something that seems so simple, I just can't get to work.
I have this nested parameter group (not sure if that's the correct term) -
build: {
configuration: '',
nugetSource: '',
dotnetVersion: '',
projectsToPublish: '',
releaseCandidate: 'False',
tag: ''
}
I'm trying to then use an 'if' to set a variable for pool, dependent on the parameters.build.dotnetVersion passed in.
- job: build
displayName: Build & test
variables:
- ${{ if eq(parameters.build.dotnetVersion,6.0.200) }}:
- name: buildpool
value: build-dotnet6
- ${{ if ne(parameters.build.dotnetVersion,6.0.200) }}:
- name: buildpool
value: build-default
pool: $(buildpool)
So even though I have confirmed with an echo command that the value of parameters.build.dotnetVersion is 6.0.200, buildpool is always getting set to build-default.
I also tried wrapping 6.0.200 in single quotes, but didn't work as expected.

Prevent Vercel Deployment on branch push

I have my GitHub Repository linked to my vercel project. Required for deploying changes on a subdomain that's linked to a branch on my git repository. dev.<website>.<tld> is linked to the dev branch. <website>.<tld> is linked to the main branch. Couldn't figure out another way to do this, other than linking to my git repo.
I have a GitHub action that runs tests amongst other things that I want to ensure pass before deployment. But every time I push changes to my production branch it kicks of a vercel deployment, that I want to avoid.
I know there is a Ignored Build Step section in the git settings on vercel, but I'm not sure what to add in the command input in this section?
I've added
[ exit 1 ]
But not sure if this is correct.
Here is my github actions workflow yml file.
name: Deploy Web Application
on:
push:
branches: ["master", "development"]
paths:
- "web/**"
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./web
strategy:
matrix:
node-version: [16.13.0]
steps:
- name: Checkout
uses: actions/checkout#v3
- name: Node Version ${{ matrix.node-version }}
uses: actions/setup-node#v3
with:
node-version: ${{ matrix.node-version }}
cache: "yarn"
cache-dependency-path: "./web/yarn.lock"
- name: Install Dependencies
run: yarn
- name: Build Project
run: yarn build
- name: Run Linting
run: yarn lint
- name: Run Typecheck
run: yarn typecheck
- name: Start Deployment
uses: bobheadxi/deployments#v0.6.2
id: deployment
with:
step: start
token: ${{ secrets.GH_TOKEN }}
env: prod
- name: Deploy to Vercel
uses: amondnet/vercel-action#v20
id: vercel-action
with:
github-token: ${{ secrets.GH_TOKEN }}
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
# if main branch go to --prod environment otherwise nothing for preview environment
vercel-args: "${{ github.ref == 'refs/heads/master' && '--prod' || '' }}"
working-directory: ./web
- name: Update Deployment Status
uses: bobheadxi/deployments#v0.6.2
if: always()
with:
step: finish
token: ${{ secrets.GH_TOKEN }}
status: ${{ job.status }}
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
env_url: ${{ steps.vercel-action.outputs.preview-url }}
You can enable the "Ignored Build Step" field by referring to the
documentation of this feature. If the command returns "0", the
build will be skipped. If, however, a code "1" or greater is
returned, then a new deployment will be built.
With a Script
#!/bin/bash
echo "VERCEL_ENV: $VERCEL_ENV"
if [[ "$VERCEL_ENV" == "production" ]] ; then
# Proceed with the build
echo "βœ… - Build can proceed"
exit 1;
else
# Don't build
echo "πŸ›‘ - Build cancelled"
exit 0;
fi
With Environment Variables
#!/bin/bash
echo "VERCEL_GIT_COMMIT_REF: $VERCEL_GIT_COMMIT_REF"
if [[ "$VERCEL_GIT_COMMIT_REF" == "staging" || "$VERCEL_GIT_COMMIT_REF" == "main" ]] ; then
# Proceed with the build
echo "βœ… - Build can proceed"
exit 1;
else
# Don't build
echo "πŸ›‘ - Build cancelled"
exit 0;
fi
With Folders and Workspaces
To build a new deployment considering only a certain folder, you can use the following command:
git diff HEAD^ HEAD --quiet ./packages/frontend/
The above was copied from here (includes more details):
How do I use the "Ignored Build Step" field on Vercel?
Video tutorial:
How to Ignore Build Step on Vercel
Another guide:
Vercel – ignore GitHub branches

Drone template not triggering build

Following is how our.drone.yml looks like (and template also listed below) this an example configuration very much how we want in our production. The reason we are using a template is that our staging and production have similar configurations with values different in them(hence circuit template). And we wanted to remove duplication using the template circuit.yaml.
But currently, we are unable to do so df I don’t define the test.yaml(template) and have test step imported without template (and have the circuit template define to avoid the duplicate declaration of staging and production build) the drone build fails with
"template converter: template name given not found
If I define the test step as a template. I see the test step working but on creating the tag I see the following error
{"commit":"28ac7ad3a01728bd1e9ec2992fee36fae4b7c117","event":"tag","level":"info","msg":"trigger: skipping build, no matching pipelines","pipeline":"test","ref":"refs/tags/v1.4.0","repo":"meetme2meat/drone-example","time":"2022-01-07T19:16:15+05:30"}
---
kind: template
load: test.yaml
data:
commands:
- echo "machine github.com login $${GITHUB_LOGIN} password $${GITHUB_PASSWORD}" > /root/.netrc
- chmod 600 /root/.netrc
- go clean -testcache
- echo "Running test"
- go test -race ./...
---
kind: template
load: circuit.yaml
data:
deploy: deploy
create_tags:
commands:
- echo "Deploying version $DRONE_SEMVER"
- echo -n "$DRONE_SEMVER,latest" > .tags
backend_image:
version: ${DRONE_SEMVER}
tags:
- '${DRONE_SEMVER}'
- latest
And the template is below
test.yaml
kind: pipeline
type: docker
name: test
steps:
- name: test
image: golang:latest
environment:
GITHUB_LOGIN:
from_secret: github_username
GITHUB_PASSWORD:
from_secret: github_token
commands:
{{range .input.commands }}
- {{ . }}
{{end}}
volumes:
- name: deps
path: /go
- name: build
image: golang:alpine
commands:
- go build -v -o out .
volumes:
- name: deps
path: /go
volumes:
- name: deps
temp: {}
trigger:
branch:
- main
event:
- push
- pull_request
circuit.yaml
kind: pipeline
type: docker
name: {{ .input.deploy }}
steps:
- name: create-tags
image: alpine
commands:
{{range .input.create_tags.commands }}
- {{ . }}
{{end}}
- name: build
image: plugins/docker
environment:
GITHUB_LOGIN:
from_secret: github_username
GITHUB_PASSWORD:
from_secret: github_token
VERSION: {{ .input.backend_image.version }}
SERVICE: circuits
settings:
auto_tag: false
repo: ghcr.io/meetme2meat/drone-ci-example
registry: ghcr.io

How to use github actions bot for testing gradle java

I am trying to implement Github-actions(bot), which runs gradle test when PR has been created.
To assure that my workflow file works as I expected, I explicitly wrote a test method which should cause failure.
#Test
fun thisShouldFail() {
assertEquals(1, 2)
}
When I try testing on my local machine, I get the log below.
> Task :test FAILED
FAILURE: Build failed with an exception.
# More
Above log indicates that there was something wrong in the test codes as I expected it to be.
But then Github actions bot runs this command, the test code result is SUCCESS.
Below is my github workflow yaml file for this action.
name: PullRequestGradleTest
on:
pull_request_target:
types: [labeled]
jobs:
test:
name: GradleTest
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'STAGING')
steps:
- name: checkout
uses: actions/checkout#v2
- name: Setup JDK 1.8
uses: actions/setup-java#v2
with:
java-version: '8'
distribution: 'adopt'
- name: Grant Permissions to gradlew
run: chmod +x gradlew
- name: Test
run: gradle test --tests "*"
- name: Test Success
if: success()
uses: actions/github-script#0.2.0
with:
github-token: ${{ github.token }}
script: |
const pull_number = "${{github.event.number}}"
await github.pulls.createReview({
...context.repo,
pull_number,
body: "All tests passed.",
event: "APPROVE"
})
- name: Test Fail
if: failure()
uses: actions/github-script#0.2.0
with:
github-token: ${{ github.token }}
script: |
const pull_number = "${{github.event.number}}"
await github.pulls.createReview({
...context.repo,
pull_number,
body: "There is something wrong with test codes.",
event: "REQUEST_CHANGES"
})
await github.pulls.update({
...context.repo,
pull_number,
state: "closed"
})
I found that you are using gradle, not gradlew.
name: PullRequestGradleTest
on:
pull_request_target:
types: [labeled]
jobs:
test:
name: GradleTest
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'STAGING')
steps:
- name: checkout
uses: actions/checkout#v2
- name: Setup JDK 1.8
uses: actions/setup-java#v2
with:
java-version: '8'
distribution: 'adopt'
- name: Grant Permissions to gradlew
run: chmod +x gradlew
- name: Test
run: ./gradlew test --tests "*"
- name: Test Success
if: success()
uses: actions/github-script#0.2.0
with:
github-token: ${{ github.token }}
script: |
const pull_number = "${{github.event.number}}"
await github.pulls.createReview({
...context.repo,
pull_number,
body: "All tests passed.",
event: "APPROVE"
})
- name: Test Fail
if: failure()
uses: actions/github-script#0.2.0
with:
github-token: ${{ github.token }}
script: |
const pull_number = "${{github.event.number}}"
await github.pulls.createReview({
...context.repo,
pull_number,
body: "There is something wrong with test codes.",
event: "REQUEST_CHANGES"
})
await github.pulls.update({
...context.repo,
pull_number,
state: "closed"
})
If you use gradle in the command, it will depend on the machine's environment. In this case, there is a possibility that occurs error because of Gradle version. Therefore, you need to use the project's Gradle which is included with your repo. The way to use is using gradlew scripts.
I also recommend following these three steps to test the branch for the pull request.
Clean -> Assemble(or build) -> Test
Base problem was that if we use pull_request_target event, the action runs on the target branch, which would be the base branch that the PR will be merged into. To solve this problem, I had to explicitly set where this action will run on.
On job => steps
steps:
- name: checkout
uses: actions/checkout#v2
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{github.event.pull_request.head.repo.full_name }}