How to run workshops in GitHub Actions¶
The launch-workshop action installs Workshop on a GitHub-hosted runner and launches an ephemeral workshop for the duration of a job. Use it to run your project’s tests, builds, or other tasks inside the same workshop you use locally, without standing up a self-hosted runner.
If you’d rather run jobs on your own hardware, use a workshop as a self-hosted runner instead; see How to run GitHub Actions locally.
Prerequisites¶
Before getting started, ensure you have:
A GitHub repository with Actions enabled
A workshop definition committed to the repository, at
workshop.yamlor.workshop/<NAME>.yaml
Add the action to a workflow¶
The smallest useful workflow checks out the repository, launches the default workshop, and runs a command inside it:
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: canonical/launch-workshop@v1
- run: workshop exec -- pytest
If the repository contains a single workshop.yaml
at the project root,
the action launches it automatically.
For repositories with several workshops under .workshop/,
set the workshop input to the one you need.
For production use, pin the action to a specific commit SHA.
The @v1 shorthand shown above tracks the latest v1.*
release and can be moved between versions;
@main is even less stable.
Test across multiple workshops¶
To test a project against several workshops in parallel,
parameterize the workshop input with a matrix:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
workshop: [dev-jammy, dev-noble]
steps:
- uses: actions/checkout@v6
- uses: canonical/launch-workshop@v1
with:
workshop: ${{ matrix.workshop }}
- run: workshop run "$WS" unit-tests
env:
WS: ${{ matrix.workshop }}
This pattern fits well for testing the same project against different Ubuntu releases, different SDK channels, or any other axis you encode in the workshop name.
Cache SDK data across runs¶
Some SDKs expose mount plugs that can be persisted between workflow runs, such as a package cache or a build cache. List the available plugs in your local workshop with workshop connections:
$ workshop connections --all
INTERFACE PLUG SLOT NOTES
mount uv:cache system:mount -
Pass the matching <SDK>:<PLUG> lines to the cache input,
one per line:
steps:
- uses: canonical/launch-workshop@v1
with:
cache: |
go:mod-cache
rust:cargo-registry
uv:cache
Each listed plug is mounted from a GitHub-managed cache, keyed by the SDK and plug name. Not every SDK defines cacheable plugs; check the SDK’s documentation when in doubt.
Inputs¶
The action exposes the following inputs:
Input |
Description |
|---|---|
|
Channel used to install the Workshop snap.
Optional; defaults to |
|
Specific revision of the Workshop snap to install. Optional. |
|
Directory containing a workshop to launch. Defaults to the repository root. |
|
Name of the workshop to launch. Required if the project defines several workshops. |
|
Mount plugs to cache across runs,
one |
Security considerations¶
When integrating the action into your workflows:
Pin the action to a commit SHA so a compromised tag cannot push unreviewed code into your workflows.
See also¶
How-to guides: