Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This workflow MUST be audited with zizmor.
# This workflow SHOULD be using pinned action refs.

name: CI

on:
push:
branches: [main]
pull_request:
workflow_dispatch: # let someone trigger the CI on their branch without a PR

permissions: {}

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true

jobs:

test:
name: Test

runs-on: ubuntu-slim

permissions:
contents: read

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Install uv
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
with:
version: "0.10.11"
enable-cache: true # not a release workflow, caching is fine

- name: Install the project
run: uv sync --locked --all-extras --dev

# Run the tests before the lint and type-check, so that we at least can
# see useful results before going and fixing nits.

- name: Test across Python versions
run: uv run tox

- name: Lint
run: uv run ruff check .

- name: Type-check
run: uv run ty check .
27 changes: 26 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,28 @@ on:
workflow_dispatch:
inputs:
tag:
# The tag should still exist, but use this if some transient error means that
# we failed to start, or complete.
#
# If we did start and it was just a failure to upload, you should consider
# re-running from the failed jobs in the existing action run, instead
# of a new run.
description: "The tag to release (e.g., v1.0.0)"
required: true

permissions: {}

# We don't want to interrupt an existing flow, and we do (or should!) have a
# tag protection ruleset preventing updates/deletions/force-pushes for v*
#
# But if something goes wrong where I want to manually create a release, we do
# have workflow_dispatch. For that, we don't cancel and we don't guard on a
# release existing. My assumption is that the draft release will have been created
# but a transient error blocked the release (PyPI service outage or somesuch).
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

jobs:

plan-release:
Expand Down Expand Up @@ -55,7 +72,15 @@ jobs:
run: |
# NOTE: No quotes around PRERELEASE_FLAG so that it expands to either `--prerelease` or an empty string,
# rather than an empty argument.
gh release create --repo "$GITHUB_REPOSITORY" --draft --verify-tag ${PRERELEASE_FLAG} "${RELEASE_TAG}" --title "${RELEASE_TAG}"
set -e # no 'u' (even though PRERELEASE_FLAG should always exist, just usually be empty)
if ! gh release create --repo "$GITHUB_REPOSITORY" --draft --verify-tag ${PRERELEASE_FLAG} "${RELEASE_TAG}" --title "${RELEASE_TAG}"
then
# record some information about the already-existing release in our output
gh release view --json id,tagName,createdAt,isDraft,isPrerelease,isImmutable "${RELEASE_TAG}"
# if that fails, then it doesn't exist and we failed to create, so abort under `-set -e` is correct
# Now, refuse to proceed if the release is no longer draft
gh release view --json isDraft "${RELEASE_TAG}" | jq -er .isDraft
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TAG: ${{ needs.plan-release.outputs.release-tag }}
Expand Down