Skip to content

Move the release into a workflow of its own - #265

Merged
Paebbels merged 4 commits into
devfrom
claude/actions-pipeline
Sep 16, 2026
Merged

Paebbels merged 4 commits into
devfrom
claude/actions-pipeline

Conversation

@pytooling-claude

@pytooling-claude pytooling-claude Bot commented Sep 15, 2026

Copy link
Copy Markdown

The release logic of this repository sits inside a test workflow: _Checking_JobTemplates.yml tags release commits and publishes release pages beside its own verification jobs. The v8.0.0 release showed what that costs:

  • TriggerTaggedRelease was skipped, because it needs PublishToGitHubPages and PDFDocumentation failed on the MiKTeX image - so the tag had to be created by hand.
  • Both fixture pipelines created the release page on the tag, and both failed trying to publish myPackage and myFramework.Extension to PyPI (34195505827, 34195505779).

This pull-request moves the release into a workflow of its own, without collecting the verification jobs into one run: the five _Checking_*.yml workflows keep their own push trigger and their own, separately readable pipelines.

New Features

  • Release.yml - a workflow holding no test jobs, so a release run stays short:
    • A merge commit on main starts it. Prepare (PrepareJob.yml) classifies the commit, and Verifications waits for the runs of the five _Checking_*.yml workflows for that commit - started by the same push - and fails if one of them didn't succeed.
      • One actions/runs?head_sha= request per pass reports every run of the commit, so a pass costs the same whether one workflow is pending or five. A workflow that concluded is dropped from the wait, and each one is reported when it finishes rather than in list order.
      • The runs of a commit are listed newest first, so the current run of a workflow is read and a superseded re-run is ignored.
      • poll_interval (15 s) and poll_timeout (6600 s) are workflow_dispatch inputs, so both can be changed for a single run. The job's timeout-minutes stays the outer bound - the loop reaches its own timeout first and names the workflows still pending.
      • A workflow with no run for the commit is reported as NO RUN after 300 s, instead of being waited out: the runs are created by the same push event, so one that is missing after that isn't coming.
    • TriggerTaggedRelease (TagReleaseCommit.yml) then tags the release commit. It compares github.ref against the main branch a second time - is_release_commit is only true for a merge commit there, but creating a tag is the one irreversible step in this workflow.
    • A tag created with the pipeline's token raises no push event, so the job template starts this workflow again through workflow_dispatch at the new tag - that is what its workflow input names, here 'Release.yml'.
    • In that run ReleasePage (PublishReleaseNotes.yml) publishes the release notes, and UpdateVersionBranch (UpdateVersionBranch.yml, prefix: 'r') opens the pull-request moving the major-version branch, titled like Updating r8 from v8.1.0 - the pull-request that was made by hand for v8.0.0 (Updating r8 from v8.0.0 #258).

Changes

  • The release jobs leave _Checking_JobTemplates.yml. TriggerTaggedRelease and ReleasePage were real release actions inside a test workflow; they live in Release.yml. TagReleaseCommit.yml and PublishReleaseNotes.yml are still exercised - by the release itself.
  • PublishOnPyPI in _Checking_JobTemplates.yml becomes a dry-run test. It ran only on a release tag and tried to upload the fixture package; it now runs on every pipeline with dry_run: 'true', so the template is exercised and nothing is published.
  • The fixture pipelines set pypi_dry_run: 'true' - the follow-up Add a dry-run mode to PublishOnPyPI #256 announced but couldn't make in its own branch, because the input didn't exist on dev yet.

Known Issues

  • ⚠️ PDFDocumentation still fails - the pytooling/miktex:sphinx image misses luaotfload-main and luatex85.sty. _Checking_JobTemplates.yml therefore doesn't succeed, and Verifications refuses the release until that is fixed. Unlike before, the refusal is stated in one job instead of silently skipping the tagging job. It also means the passing path of the gate cannot be shown yet.
  • Verifications occupies a runner while it waits - up to poll_timeout, with the job's two-hour timeout-minutes behind it. It runs for commits on main, and until the scaffold below is removed also for commits on this pull-request's branch.
  • The fixture pipelines run CompletePipeline.yml, whose own ReleasePage job also updates the release page on a tag. The text is identical - it comes from the release pull-request - but two workflows write it. Disabling that job in a verification run would need a new input on CompletePipeline.yml.

Documentation

  • Development.rst gains Releasing This Repository: what waits for the verification workflows, what tags, and why the tag run is started by workflow_dispatch.
  • Releases.rst describes the automated tagging, and keeps the manual commands as the fallback.

GitHub Pipeline

  • ⚠️ This branch is temporarily part of the push trigger of Release.yml and has to be removed before merging. Until this workflow is on main it can be started no other way: the push trigger names main, and a workflow_dispatch needs the file on the default branch. It is marked as a scaffold in the workflow.
  • The gate was proven with it, run 35066440658 on 8f36ada:
    • Prepare classified the commit in 6 s: a regular commit on a topic branch, so is_release_commit and is_release_tag are false.
    • Verifications reported _Checking_AvailableRunners.yml, _Checking_Parameters.yml, _Checking_SimplePackage_Pipeline.yml and _Checking_NamespacePackage_Pipeline.yml as [OK] in the order they finished, then _Checking_JobTemplates.yml as [failure], and refused the release after 8 m 24 s.
    • TriggerTaggedRelease, ReleasePage and UpdateVersionBranch were skipped - nothing was tagged or published from a topic branch.
  • The polling loop was checked against a stubbed gh before that run: five workflows green in one pass, a failure named and refused, a missing run reported as NO RUN without consuming the timeout, a shrinking wait list reporting each workflow exactly once over three passes, and a refusal when the timeout expires while runs are still in progress.

Related Issues and Pull-Requests

'Pipeline.yml' classifies the ref, calls the five verification workflows, tags a release commit when all of them
succeeded, and on the tag run publishes the release page and opens the pull-request moving the version branch. The
verification workflows exchange their 'push' trigger for 'workflow_call', and the release jobs leave
'_Checking_JobTemplates.yml'. The fixture pipelines and the template test publish nothing: 'pypi_dry_run' and
'dry_run' are 'true'.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
@pytooling-claude pytooling-claude Bot added CI: GitHub Actions Continuous Integration issues related to GitHub Actions (Windows, Linux and MacOS) Enhancement New feature or request Job Template Tests labels Sep 15, 2026
@codacy-production

codacy-production Bot commented Sep 15, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Coverage ∅ diff coverage · +0.00% coverage variation

Metric Results
Coverage variation +0.00% coverage variation
Diff coverage diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (3a08098) 45 41 91.11%
Head commit (8f36ada) 45 (+0) 41 (+0) 91.11% (+0.00%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#265) 0 0 ∅ (not applicable)

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.22%. Comparing base (3a08098) to head (8f36ada).
⚠️ Report is 5 commits behind head on dev.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##              dev     #265   +/-   ##
=======================================
  Coverage   82.22%   82.22%           
=======================================
  Files           1        1           
  Lines          45       45           
  Branches        9        9           
=======================================
  Hits           37       37           
  Misses          4        4           
  Partials        4        4           
Flag Coverage Δ
unittests 82.22% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…over all jobs.

'Pipeline.yml' called the five verification workflows, which collected about 170 jobs into a single run - unreadable
when one of them fails. They keep their own 'push' trigger and their own runs; the new 'Release.yml' waits for their
runs of the release commit, tags it, and on the tag run publishes the release page and opens the version-branch
pull-request.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
@pytooling-claude pytooling-claude Bot changed the title Give this repository its own pipeline, which owns the release decisions Move the release into a workflow of its own Sep 15, 2026
claude-code and others added 2 commits September 16, 2026 06:43
'Prepare' -> 'Verifications' could not be exercised before the workflow sits
on 'main': the push trigger is 'main' only, and 'workflow_dispatch' needs the
file on the default branch ('dev'), where it isn't either. The PR branch is
added to the push trigger as a scaffold, to be removed before merging.

The release jobs need no new condition to stay out of the way - 'Classify' in
'PrepareJob.yml' sets 'is_release_commit' for a merge commit on the main
branch only. 'TriggerTaggedRelease' compares the ref a second time regardless,
because creating a tag is the one irreversible step.

'Verifications' waited out its 120 minute timeout when a workflow had no run
for the commit at all: the API reports 'null', which never equals 'completed',
so the 'NO RUN' error below the loop was unreachable. The wait for a run to
appear is now bounded by 'noRunTimeout'.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
'Verifications' queried one workflow at a time and blocked on it, so a
workflow that finished later in the list stayed unseen until its turn came,
and every interval cost one request for the whole wait.

'actions/runs?head_sha=' reports every run of the commit, so one request per
pass now covers all five workflows. Runs are listed newest first, so the first
line for a workflow is its current run and a superseded re-run is ignored -
'per_page=1' had read whichever run was newest. A workflow that concluded is
removed from the wait and neither queried nor printed again.

The interval is 15 s (was 60 s), and the loop has its own timeout, both
overridable per run through the new 'poll_interval' and 'poll_timeout' dispatch
inputs. The job's 'timeout-minutes' stays the outer bound; the loop's default
of 6600 s reports the workflows still pending before that hits.

Local harness '_scratchpad/release-checks/test-poll.py' (stubbed 'gh'): all
five green in one pass, a failure named and refused, a missing run reported as
'NO RUN' without consuming the timeout, a shrinking wait list reporting each
workflow exactly once over three passes, and a refusal when the timeout
expires while runs are still in progress.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
@Paebbels
Paebbels merged commit 98890b2 into dev Sep 16, 2026
171 of 175 checks passed
@Paebbels
Paebbels deleted the claude/actions-pipeline branch September 16, 2026 20:41
@pytooling-claude pytooling-claude Bot mentioned this pull request Sep 16, 2026

This branch had an error being deployed

1 failed deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI: GitHub Actions Continuous Integration issues related to GitHub Actions (Windows, Linux and MacOS) Enhancement New feature or request Job Template Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants