Shared workflows for the ITensors Julia packages
The Tests workflow is designed to run the tests suite for Julia packages.
The workflow works best with a runtests.jl script that looks like this:
using Test
# check if user supplied args
pat = r"(?:--group=)(\w+)"
arg_id = findfirst(contains(pat), ARGS)
const GROUP = if isnothing(arg_id)
uppercase(get(ENV, "GROUP", "ALL"))
else
uppercase(only(match(pat, ARGS[arg_id]).captures))
end
@time begin
if GROUP == "ALL" || GROUP == "CORE"
@time include("test_core1.jl")
@time include("test_core2.jl")
# ...
end
if GROUP == "ALL" || GROUP == "OPTIONAL"
@time include("test_optional1.jl")
@time include("test_optional2.jl")
# ...
end
# ...
endAn example workflow that uses this script is:
name: Tests
on:
push:
branches:
- 'master'
- 'main'
- 'release-'
tags: '*'
paths-ignore:
- 'docs/**'
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
# Cancel intermediate builds: only if it is a pull request build.
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
jobs:
tests:
name: "Tests"
strategy:
fail-fast: false
matrix:
version:
- 'lts' # minimal supported version
- '1' # latest released Julia version
# optionally, you can specify the group of tests to run
# this uses multiple jobs to run the tests in parallel
# if not specified, all tests will be run
group:
- 'core'
- 'optional'
os:
- ubuntu-latest
- macOS-latest
- windows-latest
uses: "ITensor/ITensorActions/workflows/Tests.yml@main"
with:
group: "${{ matrix.group }}"
julia-version: "${{ matrix.version }}"
os: "${{ matrix.os }}"
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}By default, when a pull request is a draft, the Tests workflow only runs the
ubuntu-latest / Julia 1 (latest version) combination and skips all other
matrix entries. This gives fast feedback while saving CI minutes.
This is controlled by the run-all-on-draft input (default: false). To run
the full matrix even on draft PRs, set it to true:
uses: "ITensor/ITensorActions/workflows/Tests.yml@main"
with:
run-all-on-draft: true
# ...The documentation workflow is designed to build and deploy the documentation for Julia packages.
The workflow works best with a docs/make.jl script that looks like this:
using MyPackage
using Documenter
makedocs(; kwargs...)
deploydocs(; kwargs...)An example workflow that uses this script is:
name: "Documentation"
on:
push:
branches:
- main
tags: '*'
pull_request:
schedule:
- cron: '1 4 * * 4'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref_name != github.event.repository.default_branch || github.ref != 'refs/tags/v*' }}
jobs:
build-and-deploy-docs:
name: "Documentation"
uses: "ITensor/ITensorActions/workflows/Documentation.yml@main"
secrets: "inherit"The formatting workflows allow you to customize which directories are checked, so you can specify only the directories you want. Use the directory input to set the directory or directories for formatting (default is the root directory .). You can specify multiple directories, e.g. src test, and all will be checked by the formatter.
There are three workflows available: one for simply verifying the formatting, one for additionally applying suggested changes, and one that makes a PR to the repository formatting the code in the repository.
name: "Format Check"
on:
push:
branches:
- 'main'
tags: '*'
pull_request:
permissions:
contents: read
actions: write
pull-requests: write
jobs:
format-check:
name: "Format Check"
uses: "ITensor/ITensorActions/.github/workflows/FormatCheck.yml@main"
with:
directory: "." # Customize this to check a specific directoryThe Format Pull Request workflow has two modes depending on the trigger event:
- Schedule / dispatch mode: runs the formatter and opens a new pull request with the changes (bumping the patch version).
- On-demand mode (
issue_comment): comment/format(configurable via thetriggerinput) on a pull request to apply formatting directly to that PR branch. The bot reacts with π to confirm.
name: "Format Pull Request"
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
# Optional: allow on-demand formatting by commenting "/format" on a PR.
issue_comment:
types: [created]
permissions:
contents: write
pull-requests: write
jobs:
format-pull-request:
name: "Format Pull Request"
uses: "ITensor/ITensorActions/.github/workflows/FormatPullRequest.yml@main"
with:
directory: "." # Customize this to check a specific directory
# trigger: "/format" # Customize the on-demand trigger phrase (default: "/format")The LiterateCheck workflow is designed to keep the README of Julia packages up to date. The workflow would look like:
name: "Literate Check"
on:
push:
branches:
- 'main'
tags: '*'
pull_request:
jobs:
format-check:
name: "Literate Check"
uses: "ITensor/ITensorActions/.github/workflows/LiterateCheck.yml@main"The CompatHelper workflow is designed to periodically check dependencies for breaking
releases, and if so make PRs to bump the compat versions. By default this workflow
checks the Julia General registry
for breaking releases of dependencies, but you can add other registries
by specifying the registry URLs with the localregistry option,
which should be strings with registry URLs seperated by a newline character (\n).
Here is an example workflow:
name: "CompatHelper"
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
compat-helper:
name: "CompatHelper"
uses: "ITensor/ITensorActions/.github/workflows/CompatHelper.yml@main"
with:
localregistry: "https://github.com/ITensor/ITensorRegistry.git"Test a set of dependencies of the package against the current PR branch
to check if changes in the branch break any downstream tests. If the version
is bumped to indicate a breaking change according to semver, the test passes
since it is safe to register the changes without breaking downstream
packages if they follow semver in their compat versions.
Additionally, if some dependent packages being tested are registered in one or more
local registry, you can specify a list of local registries using their
repository URLs using the localregisty option,
which should be a string with registry URLs seperated by a newline character (\n).
Here is an example workflow:
name: "IntegrationTest"
on:
push:
branches:
- 'main'
tags: '*'
paths:
- 'Project.toml'
pull_request:
paths:
- 'Project.toml'
jobs:
integration-test:
name: "IntegrationTest"
strategy:
matrix:
pkg:
- 'BlockSparseArrays'
- 'NamedDimsArrays'
- 'TensorAlgebra'
uses: "ITensor/ITensorActions/.github/workflows/IntegrationTest.yml@main"
with:
localregistry: "https://github.com/ITensor/ITensorRegistry.git"
pkg: "${{ matrix.pkg }}"By default, integration tests are skipped entirely for draft PRs. This is
controlled by the run-on-draft input (default: false). To run integration
tests even on draft PRs, set it to true:
uses: "ITensor/ITensorActions/.github/workflows/IntegrationTest.yml@main"
with:
run-on-draft: true
# ...Additionally, it is possible to run these tests dynamically, whenever a comment on a PR is detected.
For example, a workflow that detects @integrationtests Repo/Package.jl looks like:
name: "Integration Request"
on:
issue_comment:
types: [created]
jobs:
integrationrequest:
if: |
github.event.issue.pull_request &&
contains(fromJSON('["OWNER", "COLLABORATOR", "MEMBER"]'), github.event.comment.author_association)
uses: ITensor/ITensorActions/.github/workflows/IntegrationRequest.yml@main
with:
localregistry: https://github.com/ITensor/ITensorRegistry.gitThe VersionCheck workflow is designed to check if the package version has been increased with respect to the latest release.
The workflow would look like:
name: "Version Check"
on:
pull_request:
jobs:
version-check:
name: "Version Check"
uses: "ITensor/ITensorActions/.github/workflows/VersionCheck.yml@main"
with:
localregistry: https://github.com/ITensor/ITensorRegistry.gitThe Registrator workflow registers a new package version whenever the version in
Project.toml is bumped on the main branch. It automatically routes to the
General registry for packages
already registered there, or to a local registry otherwise.
When a commit is pushed to main/master that changes Project.toml, the workflow
checks whether the version has increased and, if so, triggers registration. The version
bump must follow semver (patch, minor, or major increment by exactly 1).
Comment /register on any issue to force registration of the current HEAD of the
default branch. You can also specify a particular commit SHA to register a non-latest
commit:
/register
/register abc1234
The bot reacts with π to confirm the trigger. On-demand registration bypasses the version-change check, so it works even if the version was not bumped in the most recent commit.
name: "Register Package"
on:
workflow_dispatch: ~
push:
branches:
- "master"
- "main"
paths:
- "Project.toml"
# Optional: allow on-demand registration by commenting "/register" on an issue.
issue_comment:
types:
- "created"
permissions:
contents: "write"
pull-requests: "write"
issues: "write"
jobs:
Register:
uses: "ITensor/ITensorActions/.github/workflows/Registrator.yml@main"
with:
localregistry: "ITensor/ITensorRegistry" # omit if package is in General
secrets: "inherit"| Input | Description | Default |
|---|---|---|
localregistry |
Local registry repo (owner/name) for packages not in General |
"" |
trigger |
Comment trigger phrase for on-demand registration | /register |
julia-version |
Julia version used by the workflow | 1 |
| Secret | Required | Description |
|---|---|---|
REGISTRATOR_KEY |
For local registry only | A PAT with write access to the local registry repo, used to check it out and open a registration PR |
The TagBot workflow creates GitHub releases and tags whenever a new version of a package is registered in a Julia registry. It runs two jobs in parallel β one scanning ITensorRegistry and one scanning the General registry β so a package registered in either registry is handled automatically.
-
General registry: The General registry has its own TagBotTriggers workflow that posts a comment as
JuliaTagBoton a trigger issue in each package repo whenever a new version is merged. This fires theissue_commentevent that starts TagBot. -
ITensorRegistry: The ITensorRegistry has a matching TagBotTriggers workflow that fires
workflow_dispatchon the package'sTagBot.ymldirectly after each registration PR is merged. This requires aTAGBOT_PATsecret in ITensorRegistry withactions: writepermission on the ITensor package repos.
name: "TagBot"
on:
issue_comment:
types:
- "created"
workflow_dispatch: ~
jobs:
TagBot:
if: "github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'"
uses: "ITensor/ITensorActions/.github/workflows/TagBot.yml@main"
secrets: inherit| Secret | Required | Description |
|---|---|---|
TAGBOT_PAT |
No | Personal access token used to authenticate with GitHub. Falls back to the built-in GITHUB_TOKEN if not provided. |
DOCUMENTER_KEY |
No | SSH deploy key used to trigger documentation workflows after a release is created. |