Morrison-Lab/gha
Central, reusable GitHub Actions for R-package and Quarto repositories
This site documents Morrison-Lab/gha, a set of reusable GitHub Actions shared across the d-morrison, UCD-SERG, ucdavis, UCLA-PHP, and UCD-IDDRC owners. It is modeled on r-lib/actions and easystats/workflows: a repo calls a shared workflow with a tiny stub instead of carrying its own copy.
The repo is public so it can be referenced from repositories across those owners.
How it works
Each capability ships as two layers:
- A composite action (for example
check-bibliography-dois/action.yml) bundles the real steps and any helper script. It is referenced asMorrison-Lab/gha/<name>@vN(the major tag that capability currently recommends - see Versioning). - A reusable workflow (
.github/workflows/<name>.yml,on: workflow_call) wraps the composite, declares permissions, and checks out the caller’s repo. This is what consumer repos target.
A consumer repo adds a small caller stub (see the examples/ directory):
name: Check Bibliography DOIs
on:
push: { branches: [main] }
pull_request:
workflow_dispatch:
jobs:
check:
uses: Morrison-Lab/gha/.github/workflows/check-bibliography-dois.yml@v2Pin to the major tag that capability currently recommends (@v2 in the example above) - it varies per capability rather than defaulting uniformly to @v1; see Versioning for the full breakdown. Do not reference @main from consumers.
Actions vs. workflows
A composite action is a list of steps. It runs inside a job that already exists - the caller’s runner and permissions are already in place. An action has no concept of jobs or triggers; it is just a named bundle of commands.
# <name>/action.yml
name: My Action
description: Does a thing
inputs:
my-input:
description: ...
runs:
using: composite
steps:
- run: echo "hello"
shell: bashA reusable workflow is a complete pipeline. It defines its own jobs, each with its own runner (runs-on:), permissions (permissions:), and steps. A consumer calls it as a job, not as a step.
# .github/workflows/<name>.yml
on: workflow_call
jobs:
my-job:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- run: echo "hello"shell: is required in composite actions
Every run: step in a composite action must declare shell:. Workflows have a default shell; composite actions do not.
| Composite action | Reusable workflow | |
|---|---|---|
| Key top-level keys | name, description, inputs, outputs, runs |
on, jobs |
| Jobs | No - only steps under runs |
Yes - one or more jobs blocks |
runs-on |
Absent - inherits the caller’s runner | Per job |
permissions |
Absent | Yes (caller must also grant them) |
| Called from | A job’s steps (via uses) |
A workflow’s jobs (via uses) |
Because an action cannot declare permissions or choose its runner, this repo uses the two-layer design: the composite action holds the real logic, and the reusable workflow wraps it to handle the runner, permissions, and checkout. Consumer repos reference only the workflow layer.
Where to go next
- Workflows catalogs every reusable workflow and what it does.
- Permissions lists the
GITHUB_TOKENpermissions and secrets each one needs. - Versioning explains the moving major tags (
@v1/@v2, per capability) and how third-party actions are pinned.
This very site is built and shipped by the workflows it documents: quarto-publish deploys it to GitHub Pages, and the preview family renders a preview for each pull request.