GitHub Actions Matrix sharing the Same Code CheckOut - yaml

I tried to perform step actions/checkout#v3 once on chained jobs, but it seems like the "build" job does not get the code. I'm getting an error "can't find the project".
Can I call actions/checkout # v3 once for two jobs?
It works when I call the code checkout twice.
name: publish-nuget
on:
push:
branches:
- main
jobs:
prepare:
runs-on: ubuntu-latest
- name: Checkout code
uses: actions/checkout#v3
- name: Get package version
id: get_package_version
uses: kzrnm/get-net-sdk-project-versions-action#v1.3.0
with:
proj-path: ProjectOne.csproj
build:
needs: prepare
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout#v3
# Add the projects path below
strategy:
matrix:
projects: [
'ProjectOne.csproj',
'ProjectTwo.csproj',
]
steps:
- name: Pack NuGet
run: dotnet pack ${{ matrix.projects }} -p:PackageVersion=${{ env.PACKAGE_VERSION }} --configuration Release
It does not work when I call the code checkout once (on the 'prepare' job).
name: publish-nuget
on:
push:
branches:
- main
jobs:
prepare:
runs-on: ubuntu-latest
- name: Checkout code
uses: actions/checkout#v3
- name: Get package version
id: get_package_version
uses: kzrnm/get-net-sdk-project-versions-action#v1.3.0
with:
proj-path: ProjectOne.csproj
build:
needs: prepare
runs-on: ubuntu-latest
steps:
# Add the projects path below
strategy:
matrix:
projects: [
'ProjectOne.csproj',
'ProjectTwo.csproj',
]
steps:
- name: Pack NuGet
run: dotnet pack ${{ matrix.projects }} -p:PackageVersion=${{ env.PACKAGE_VERSION }} --configuration Release

Having a job being dependent on another job, is just for logical purposes and not state or artifact dependency sharing. You are actually runing the 2 jobs on 2 different agents. If you want to share something from the prepare job, you can use the cache or artifact API. E.g. using the cache API to cache the path 'somePath'. Same step for downloading the cache.
- name: Cached build artifacts
uses: actions/cache#v2
id: artifactcache
with:
path: somePath
key: buildArtifacts${{ github.run_number}}
As you are not gaining anything form splitting this up into 2 jobs, I would run everything in a single job instead.

Related

GitHub Actions restrict job with tag validation using if condition or github ref

I have an application code which runs the maven builds we created snapshots and then create a tag created once the snapshot build is successful, and then we use the tag created in the snapshot build and then run the build using the tag for release using the GitHub actions workflows.
now I'm trying to run the release of the build workflow job only if the tag as matching and if the tag, not matches, skip the jobs or fails the jobs, let's say the tag will be created in the snapshot build and will use tag format as "<appname>-<app_build_type>-<github-actions-run_number>-<env>-origin/<branch>" and the actual tag looks like "java-maven-44-dev-origin/develop"
I was trying the below 2 methods workflows, but it is not at all working
1st Method is:
name: maven-release
on:
workflow_dispatch:
jobs:
checkout_code:
runs-on: [ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout#v3
with:
fetch-depth: 0
maven_build:
runs-on: [ubuntu-latest]
if: ${{ github.ref == 'refs/tags/*-origin/develop' }}
needs: checkout_code
steps:
- name: Run maven build
run: |
mvn clean install
2nd Method is:
name: maven-release
on:
workflow_dispatch:
jobs:
checkout_code:
runs-on: [ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout#v3
with:
fetch-depth: 0
maven_build:
runs-on: [ubuntu-latest]
if: contains(github.ref, 'refs/tags/*-origin/develop')
needs: checkout_code
steps:
- name: Run maven build
run: |
mvn clean install
I want to skip/fail the at job level only and no in run command, if anyone knows any solution to this or anyone can provide some suggestions on how to achieve this
Its it's possible for your use case, you could trigger your workflow on push and then apply your filter to the branch or tag
name: maven-release
on:
workflow_dispatch:
push:
tags:
- '*-origin/develop'
jobs:
checkout_code:
runs-on: [ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout#v3
with:
fetch-depth: 0
maven_build:
runs-on: [ubuntu-latest]
if: ${{ github.ref == 'refs/tags/*-origin/develop' }}
needs: checkout_code
steps:
- name: Run maven build
run: |
mvn clean install
The Github filter pattern cheat sheet
For the workflows for which each task needs to be executed only on a particular tag, then we can make use of below snipped
name: maven_build
on:
workflow_dispatch:
jobs:
checkout:
runs-on: [ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout#v3
with:
fetch-depth: 0
maven_build:
runs-on: [ubuntu-latest]
if: startsWith(github.ref, 'refs/tags/') && !contains(github.ref')
needs: checkout
steps:
- name: Run maven build command
run: |
mvn clean install
The above snippet will run only when the checkout branch matches a tag

Reuse output variables from previous job

I'm trying to run 'publish-storybook' job conditionally, based on the variable from the previous job. Complete action file:
name: Release
on:
push:
branches: [main]
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout#v3
- name: Setup Node
uses: actions/setup-node#v3.2.0
with:
node-version-file: ".nvmrc"
cache: "yarn"
- name: Install Dependencies
run: yarn install
- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action#v1
with:
publish: yarn release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_PUBLISH_KEY }}
- name: Send a message if a publish happens
if: steps.changesets.outputs.published == 'true'
run: echo "A new version of ${GITHUB_REPOSITORY} was published!"
publish-storybook:
name: Publish Storybook
runs-on: ubuntu-latest
needs: release
if: needs.release.outputs.published == 'true'
steps:
- name: Checkout Repo
uses: actions/checkout#v3
- name: Setup Node
uses: actions/setup-node#v3.2.0
with:
node-version-file: ".nvmrc"
cache: "yarn"
- name: Install Dependencies
run: yarn install
- name: Storybook deploy
env:
GH_TOKEN: ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}
run: yarn storybook:deploy
The message A new version of ${GITHUB_REPOSITORY} was published! gets printed out in the output but a subsequent job that has a condition: if: needs.release.outputs.published == 'true' doesn't start, so there must be something wrong with this condition.
You're only defining steps.outputs and not job.outputs.
jobs:
release:
name: Release
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
published: ${{ steps.changesets.outputs.published }}
steps:
[... no further changes]
See also:
https://docs.github.com/en/actions/using-jobs/defining-outputs-for-jobs

Run command taking output from previous step on GitHub actions

I'm trying to make a GitHub action that builds a Hugo website, deploys it on Pinata and saves the output hash of this last step to a txt file. I managed to achieve the first and second steps. And, for the third one, I've been trying to do it by running an "echo" command. However, I get this message: "You have an error in your yaml syntax on line 36"
How do I run the script taking the output from the step identified as "ipfs-pin"?
Here's my code:
name: deploy
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#master
- uses: jakejarvis/hugo-build-action#master
with:
args: --minify --buildDrafts
- uses: anantaramdas/ipfs-pinata-deploy-action#v1.6.4
id: ipfs-pin
with:
pin-name: '[my-pin-name]'
path: './public'
pinata-api-key: [API Key]
pinata-secret-api-key: [secret API Key]
verbose: true
remove-old: true
saves-hash-on-file:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v2
- uses: actions/setup-node#v2
with:
node-version: '14'
- run: echo ${{steps.build.ipfs-pin.hash}} > /.github/ipfs-hash.txt
First
It seems your indentation has a problem, I reproduced the workflow to correct it without returning error when pushing the workflow on the repository:
name: Deploy
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
outputs:
hash: ${{ steps.ipfs-pin.outputs.hash }}
steps:
- uses: actions/checkout#master
- uses: jakejarvis/hugo-build-action#master
with:
args: --minify --buildDrafts
- uses: anantaramdas/ipfs-pinata-deploy-action#v1.6.4
id: ipfs-pin
with:
pin-name: '[my-pin-name]'
path: './public'
pinata-api-key: '[API Key]'
pinata-secret-api-key: '[secret API Key]'
verbose: true
remove-old: true
saves-hash-on-file:
runs-on: ubuntu-latest
needs: [build]
steps:
- uses: actions/checkout#v2
- uses: actions/setup-node#v2
with:
node-version: '14'
- run: echo ${{steps.build.outputs.hash}} > /.github/ipfs-hash.txt
Second
As you can see on the workflow above, I added the outputs field at the job1 (build) level, without this you can't share the output on other jobs.
Reference about outputs
Moreover, to share outputs between jobs, you will have to add the needs: [build] line at the job2 (saves-hash-on-file) level.
Note: I couldn't run it successfully as I don't have any credential to test, but it should work if you copy/paste the workflow I shared using your credentials.

Issues creating a CD based release on Github (WPF .NET 5.0)

I'm trying to put together a CI / CD pipeline for GitHub and strugglign with attaching my build artifact to the release. Here's my ci.yml
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
Build:
runs-on: windows-latest
env:
BuildPath: ${{ github.workspace }}\BuildTesting\bin\Release\net5.0-windows
steps:
- uses: actions/checkout#v2
- name: Setup .NET SDK
uses: actions/setup-dotnet#v1.8.1
with:
dotnet-version: 5.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Upload a Build Artifact
uses: actions/upload-artifact#v2.2.4
with:
name: thingy
path: ${{ github.workspace }}\BuildTesting\bin\Release\net5.0-windows
retention-days: 1
That runs well and I get a release artifact:
I was under the impression I'd be able to download that existing artifact but I couldn't get my head around why actions/download-artifact isn't downloading anything. So I found another article and in their cd step they were re-building, so I figured that in doing that at least I'd have a fresh build in the cd workflow to pull from. So I create a release triggered on tag push events. I can't use most zip utilities becuase they don't run on windows. I have to user windows-latest as the target framework for WPF desktop applications has to be net5.0-windows and using ubuntu-latest it fails. I tried papeloto/action-zip#v1 and in one case I managed to get a zip file which then attached to the release successfully but was only 22 bytes, so empty once I downloaded it. Here's my cd.yml:
name: CD
on:
push:
tags:
- '*'
jobs:
Release:
runs-on: windows-latest
env:
BuildPath: ${{ github.workspace }}\BuildTesting\bin\Release\net5.0-windows
ZipName: TheThing.zip
steps:
# Build the solution
- uses: actions/checkout#v2
- name: Setup .NET SDK
uses: actions/setup-dotnet#v1.8.1
with:
dotnet-version: 5.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Zip the release
uses: << What should I use to zip ${{ env.BuildPath }} ? >>
# Create a Release on the GitHub project
- name: Create release
id: create_release
uses: actions/create-release#v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: false
prerelease: false
# Upload the Build Artifact to the Release
- name: Update release asset
id: upload-release-asset
uses: actions/upload-release-asset#v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: .\${{ env.ZipName }}
asset_name: ${{ env.ZipName }}
asset_content_type: application/zip
Can anyone please recommend a GitHub action for zipping a folder that will work for windows-latest ... or another approach?
Long term I want to go with semantic versioning but GitVersion overwhelmed me last time I tried, granted I'd never working with yml builds before. I'd like to keep this as simple as possible as I'm starting to grok the basics of what's going on and once I get past this I'll start looking into GitVersion.
I'm using a test repository located here so you can see the whole thing.
You may use PowerShell to zip your artifacts using 7Zip. Please check my repository in GitHub. That compile a WPF app, compress the artifacts, create a prerelease and upload files under that release.

Can you have multiple working directories with github actions?

So I have a repo with multiple directories for multiple go projects. Is there a way to run github actions on multiple working directories so I don't have to have redundant yaml with github actions? To automate an error check with golang, I currently have:
errcheck:
name: Errcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#master
- name: check
uses: grandcolline/golang-github-actions#v1.1.0
working-directory: ./app1
with:
run: errcheck
token: ${{ secrets.GITHUB_TOKEN }}
But I'd like to have:
errcheck:
name: Errcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#master
- name: check
uses: grandcolline/golang-github-actions#v1.1.0
working-directory: [./app1, ./app2]
with:
run: errcheck
token: ${{ secrets.GITHUB_TOKEN }}
In order to run something in more than one working directory, I believe you have two options:
Option 1: Matrix
Use GitHub Action's jobs.<job_id>.strategy.matrix option. This will create multiple jobs, each with its own matrix (directory) value.
Here is a sample workflow:
name: Test
on:
push: { branches: master }
jobs:
test:
name: Matrix test
runs-on: ubuntu-latest
strategy:
matrix: { dir: ['some-dir', 'other-dir'] }
steps:
- name: Checkout code
uses: actions/checkout#v2
- name: Do something with the matrix value
working-directory: ${{ matrix.dir }}
run: pwd
Running this will create two jobs:
Option 2: Custom Shell Script
If the matrix option is not suitable for your needs, a simple shell script that loops through and tests all your nested applications (directories) might be appropriate. In this case, you ignore the working-direcoty directive in the workflow YAML, and let the script cd to each of them.
For example:
#!/usr/bin/env bash
dirs=( some-dir other-dir )
for dir in "${dirs[#]}"; do
pushd "$dir"
pwd # Do something more significant here
popd
done

Resources