diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4889741..61ab385 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,8 @@ on: push: branches: [main] pull_request: + # the Deck model workflow dispatches CI on the pull request it opens + workflow_dispatch: permissions: contents: read @@ -18,7 +20,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.11", "3.12", "3.13"] + python-version: ["3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 8bdfb96..321840c 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -1,10 +1,12 @@ name: Commit messages -# Pull requests only: the PR title and the PR's commits follow Conventional Commits. Commits pushed to main directly -# are not checked. +# Pull requests: the PR title and the PR's commits follow Conventional Commits. Commits pushed to main directly are +# not checked. Dispatched on a branch (the Deck model workflow does so for the pull request it opens): the branch's +# commits since main. on: pull_request: types: [opened, edited, synchronize, reopened] + workflow_dispatch: permissions: contents: read @@ -22,11 +24,14 @@ jobs: - name: Install commitlint run: npm install --no-save --no-package-lock @commitlint/cli@19 @commitlint/config-conventional@19 - name: Pull request title + if: github.event_name == 'pull_request' env: TITLE: ${{ github.event.pull_request.title }} run: printf '%s\n' "$TITLE" | npx --no-install commitlint --verbose - - name: Pull request commits - run: >- - npx --no-install commitlint --verbose - --from ${{ github.event.pull_request.base.sha }} - --to ${{ github.event.pull_request.head.sha }} + - name: Commits + env: + BASE: ${{ github.event.pull_request.base.sha }} + HEAD: ${{ github.event.pull_request.head.sha || github.sha }} + run: | + from=${BASE:-$(git merge-base origin/main "$HEAD")} + npx --no-install commitlint --verbose --from "$from" --to "$HEAD" diff --git a/.github/workflows/deck.yml b/.github/workflows/deck.yml index ade1964..8b8a57c 100644 --- a/.github/workflows/deck.yml +++ b/.github/workflows/deck.yml @@ -2,13 +2,15 @@ name: Deck model # nnnotes builds the deck model, the crate ournotes-sim of the ournotes-deck repository, at the commit rust/Cargo.toml # pins, so that one nnnotes version always carries one deck model. When ournotes-deck's main moves past that commit, -# this opens a pull request that moves the pin; CI then builds and tests it like any change. +# this opens a pull request that moves the pin and dispatches CI and the commit message check on its branch (a pull +# request opened with the workflow token starts no workflow by itself); their checks land on the pull request. on: schedule: - cron: "17 3 * * *" workflow_dispatch: permissions: + actions: write contents: write pull-requests: write @@ -38,7 +40,8 @@ jobs: run: | sed -i -E 's/(rev = ")${{ steps.deck.outputs.pinned }}(")/\1${{ steps.deck.outputs.head }}\2/' Cargo.toml cargo update -p ournotes-sim - - uses: peter-evans/create-pull-request@v7 + - uses: peter-evans/create-pull-request@v8 + id: pr if: steps.deck.outputs.move == 'true' with: branch: deck/update @@ -50,3 +53,10 @@ jobs: Music data files made after this change name the new commit in `provenance.deck.commit`; their deck statistics may differ. + - name: Check the pull request + if: steps.pr.outputs.pull-request-operation == 'created' || steps.pr.outputs.pull-request-operation == 'updated' + env: + GH_TOKEN: ${{ github.token }} + run: | + gh workflow run ci.yml --repo "$GITHUB_REPOSITORY" --ref deck/update + gh workflow run commitlint.yml --repo "$GITHUB_REPOSITORY" --ref deck/update diff --git a/tests/test_repo.py b/tests/test_repo.py index c1d9b08..1a9e75b 100644 --- a/tests/test_repo.py +++ b/tests/test_repo.py @@ -37,13 +37,21 @@ def workflow_triggers(text: str) -> list[str]: return events -def test_commit_messages_are_checked_on_pull_requests_only(): +def test_commit_messages_are_checked_on_pull_requests_and_dispatched_branches(): text = (ROOT / ".github" / "workflows" / "commitlint.yml").read_text(encoding="utf-8") - assert workflow_triggers(text) == ["pull_request"] + assert workflow_triggers(text) == ["pull_request", "workflow_dispatch"] assert "event_name == 'push'" not in text and "github.event.before" not in text assert "github.event.pull_request.title" in text and "github.event.pull_request.base.sha" in text +def test_the_deck_pin_pull_request_gets_its_checks(): + workflows = ROOT / ".github" / "workflows" + deck = (workflows / "deck.yml").read_text(encoding="utf-8") + for name in ("ci.yml", "commitlint.yml"): + assert "workflow_dispatch" in workflow_triggers((workflows / name).read_text(encoding="utf-8")) + assert f"gh workflow run {name} --repo \"$GITHUB_REPOSITORY\" --ref deck/update" in deck + + @pytest.mark.parametrize("name", ["README.md", "README.en.md"]) def test_determinism_is_stated_with_its_condition(name): text = (ROOT / name).read_text(encoding="utf-8")