GitHub Actions
Tips and Tricks
Run a GitHub Action workflow step if a file exists
- name: Is file created?
if: ${{ hashFiles('test.txt') != '' }}
run: echo "File exists"Continue on error
See documentation
# Linting is not working and immediately fails
- name: Lint code
run: pnpm lint
- name: Format code
if: always()
run: pnpm format
- name: Build code
if: always()
run: pnpm buildWarning: Avoid using always for any task that could suffer from a critical failure, for example: getting sources, otherwise the workflow may hang until it times out. If you want to run a job or step regardless of its success or failure, use the recommended alternative:
if: ${{ !cancelled() }}SSH Issues
When performing Git operations, you might encounter the following
Error: authentication required # ![code error]Or after installing the SSH key, you might encounter
Could not open a connection to your authentication agent. # ![code error]Possible solution
Manually set up SSH key in the Workflow
- name: Set up SSH key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hostsOutput to stdout (standard output)
In CI/CD workflows like GitHub Actions, everything printed to stdout (standard output) by a script will be captured and assigned to variables if you're using command substitution (e.g., ENV_VARIABLE=$(...)). This means loggins statements like this (in JavaScript);
console.log('Task created with keys');Will be capture by the GitHub Actions as an entire output.
Solution
- using console.error() instead of console.log() (stderr)
- Filter the output
## Cheatsheet
```sh
# Using secrets in a file
# act.secrets should be written as a simple key/value as in env files e.g.
# GITHUB_TOKEN=your_token
act --secret-file ../location-of-secret-file/act.secretsComposite Actions
Example from GitHub Docs
name: 'Hello World'
description: 'Greet someone'
inputs:
who-to-greet: # id of input
description: 'Who to greet'
required: true
default: 'World'
outputs:
random-number:
description: 'Random number'
value: ${{ steps.random-number-generator.outputs.random-number }}
runs:
using: 'composite'
steps:
- name: Set Greeting
run: echo "Hello $INPUT_WHO_TO_GREET."
shell: bash
env:
INPUT_WHO_TO_GREET: ${{ inputs.who-to-greet }}
- name: Random Number Generator
id: random-number-generator
run: echo "random-number=$(echo $RANDOM)" >> $GITHUB_OUTPUT
shell: bash
- name: Set GitHub Path
run: echo "$GITHUB_ACTION_PATH" >> $GITHUB_PATH
shell: bash
env:
GITHUB_ACTION_PATH: ${{ github.action_path }}
- name: Run goodbye.sh
run: goodbye.sh
shell: bashReuse workflow and steps
How to reuse workflows and steps in GitHub Actions (2024)
For larger units of work, a reusable workflow should be used. A composite action should be used for smaller units of work that may run on the same runner and share the same work area.
GitHub repo
Using secrets in a composite action
"Reusable workflows has secrets but actions are limited to inputs" - StackOverflow
↓
# Use action inputs to pass secrets
name: 'test'
description: 'test'
inputs:
token:
description: 'A Github PAT'
required: true
runs:
using: 'composite'
steps:
- name: Create Branch
run: echo "git branch test"
env:
GITHUB_TOKEN: ${{ inputs.token }}
shell: bashResources
Web Performance
Lighthouse
Lighthouse with WPT Network Emulation Profiles, Github Action Edition
Uses Puppeteer to start up Chrome with network emulation settings defined by WebPageTest. Supports saving of artifacts to the Github Action run. Supports custom Lighthouse configuration via JavaScript file. Supports Lighthouse budget.json for failing PRs. Supports Lighthouse-based data model scores.js for failing PRs based on any audit score or category. Posts results of audit run as a comment on your PR.
name: Audit Web Performance
on: [pull_request]
jobs:
perf:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Generate Lighthouse Report
uses: justinribeiro/lighthouse-action@master
with:
secret: ${{ secrets.GITHUB_TOKEN }}
url: https://${{ github.sha }}-dot-${{ secrets.GAE_PID }}.appspot.com
wptConnectionSpeed: threegfast
- name: Saving Lighthouse Audit Artifacts
uses: actions/upload-artifact@master
with:
name: lighthouse-artifacts
path: './results'act - Running GitHub Actions locally
GitHub Repo
Run a specific workflow
act -W '.github/workflows/checks.yml'Using secrets
# Directly in command
act -s MY_SECRET=somevalue
# Using secrets in a file
act --secret-file my.secretsGitHub Token
- Manually create a personal access token and pass it to act
act -s GITHUB_TOKEN=[insert token or leave blank and omit equals for secure input]- Using GitHub CLI directly
act -s GITHUB_TOKEN="$(gh auth token)"Pass Inputs to Workflow
act --input NAME=somevalue
# Using a file (same format as a .env)
act --input-file my.inputGithub as a database
You should not use Git as a database
Common issues
Node.js
npm not found in GitHub action
Issue
err: zsh:11: command not found: npmSolution
The problem is that NVM installs node.js to a user's local directory, and updates that user's .profile.
n=$(which node);n=${n%/bin/node}; chmod -R 755 $n/bin/*; sudo cp -r $n/{bin,lib,share} /usr/localDigitalOcean
How To Install Node.js with NVM (Node Version Manager) on a VPS (deprecated article)