Repository of reusable GitHub Actions.
- Trivy — security scan
- Report failed vulnerability check
- Docker publish
- NPM version bump
- Clean npm overrides
- NPM release — direct version bump
The trivy-scan composite action uses Trivy to scan the checked-out repository source code for security vulnerabilities.
Create a .github/workflows/security.yml file in your repository. The example supports both master and main; remove either branch if your repository uses only one. Check out its source before invoking the remote action:
name: Security Scan
on:
workflow_dispatch:
push:
branches: [master, main]
pull_request:
branches: [master, main]
schedule:
- cron: "0 6 * * 1"
jobs:
trivy:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: yboyer/actions/trivy-scan@5c400ee78c4b0775652ddecebe811c238233affe # v1.4.0The report-failure composite action creates one open incident issue for a failed scheduled vulnerability check, then updates it on later failures. Add it as a step in the vulnerability-check job after the scan:
jobs:
trivy:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: yboyer/actions/trivy-scan@5c400ee78c4b0775652ddecebe811c238233affe # v1.4.0
- name: Report failed vulnerability check
if: ${{ failure() && github.event_name == 'schedule' }}
uses: yboyer/actions/report-failure@5c400ee78c4b0775652ddecebe811c238233affe # v1.4.0The caller job needs issues: write; repository workflow permissions must also allow the GITHUB_TOKEN to create and edit issues.
The docker-publish composite action builds, tags, and publishes an image to GHCR. It creates semver tags and latest.
The job grants contents: read so actions/checkout can fetch the source, and packages: write so GITHUB_TOKEN can publish the image to GHCR.
For GHCR uploads, add the optional authentication step before docker-publish, as shown below.
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: yboyer/actions/docker-publish@5c400ee78c4b0775652ddecebe811c238233affe # v1.4.0
with:
image: ghcr.io/yboyer/example/api
dockerfile: ./.docker/Dockerfile.api
secrets: |
token=${{ secrets.TOKEN }}The secrets input uses the same id=value format as docker/build-push-action. The Dockerfile can consume the above secret with RUN --mount=type=secret,id=token ....
Docker tags are derived from the checked-out Git ref. Check out the release tag before invoking this action, including for manually orchestrated releases.
The npm-bump-version action increments a package version, commits the changed manifest on the primary branch, then creates and pushes its v<version> tag. It does not create a pull request.
name: Bump version
on:
workflow_dispatch:
inputs:
release_type:
description: Version increment
required: true
default: patch
type: choice
options: [major, minor, patch, premajor, preminor, prepatch, prerelease]
jobs:
bump:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- uses: yboyer/actions/npm-bump-version@5c400ee78c4b0775652ddecebe811c238233affe # v1.4.0
with:
release-type: ${{ inputs.release_type }}The action requires contents: write. Check out the repository's primary branch with full history before invoking it.
The clean-npm-overrides composite action removes each override that can be dropped while retaining a passing production high-severity audit. It exposes changed and removed-overrides outputs; use the former to create a pull request only when manifests changed.
The caller must check out the repository and set up Node.js before invoking the action. This example runs monthly and can also be dispatched manually:
name: Clean npm overrides
on:
workflow_dispatch:
schedule:
- cron: "0 4 1 * *"
permissions:
contents: write
pull-requests: write
concurrency:
group: clean-npm-overrides
cancel-in-progress: false
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .node-version
cache: npm
- id: overrides
uses: yboyer/actions/clean-npm-overrides@5c400ee78c4b0775652ddecebe811c238233affe # v1.4.0
- name: Create pull request
if: steps.overrides.outputs.changed == 'true'
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
branch: chore/remove-npm-overrides
delete-branch: true
add-paths: |
package.json
package-lock.json
commit-message: "chore(deps): remove unnecessary npm overrides"
title: "chore(deps): remove unnecessary npm overrides"
body: |
Removed npm overrides: ${{ steps.overrides.outputs.removed-overrides }}
Generated by the Clean npm overrides workflow.Use this workflow when version bumps are committed directly to the primary branch instead of through a release pull request. bump runs manually; publish waits for it, then publishes the new tag. It also runs when a v*.*.* tag is pushed directly.
name: Release
on:
workflow_dispatch:
inputs:
release_type:
description: Version increment
required: true
default: patch
type: choice
options: [major, minor, patch, premajor, preminor, prepatch, prerelease]
push:
tags:
- 'v*.*.*'
jobs:
bump:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
tag: ${{ steps.bump.outputs.tag }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- id: bump
uses: yboyer/actions/npm-bump-version@5c400ee78c4b0775652ddecebe811c238233affe # v1.4.0
with:
release-type: ${{ inputs.release_type }}
publish:
needs: bump
# Run for pushed tags, or after a successful manual bump.
if: ${{ always() && (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && needs.bump.result == 'success')) }}
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
env:
RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && needs.bump.outputs.tag || github.ref_name }}
RELEASE_REF: ${{ github.event_name == 'workflow_dispatch' && needs.bump.outputs.tag || github.ref }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ env.RELEASE_REF }}
# Add the project checks before publication if needed
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .node-version
- run: npm ci
- run: npm test --if-present
- run: npm run build --if-present
- run: npm publish --provenance --access public
- name: Create GitHub release
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
with:
tag_name: ${{ env.RELEASE_TAG }}
name: ${{ env.RELEASE_TAG }}
generate_release_notes: truenpm-bump-version needs contents: write; a full checkout history is not required for this direct version-bump workflow. publish depends on bump for a manual run, but still runs for a pushed tag because always() prevents its skipped dependency from skipping the job. The example uses npm publish directly: npm-bump-version has already created the tag, whereas npm-release-publish only publishes when it creates that tag itself. id-token: write enables npm trusted publishing.