Skip to content

Updating r8 from v8.1.0 - #266

Merged
Paebbels merged 37 commits into
r8from
update/r8
Sep 17, 2026
Merged

Paebbels merged 37 commits into
r8from
update/r8

Conversation

@pytooling-claude

Copy link
Copy Markdown

Moves the r8 branch consumers pin to, from v8.0.0 to v8.1.0.

The branch carries main's content with every self-reference rewritten from @main to @r8 - 71 references across 10 workflow files, so a consumer pinning @r8 gets a consistent set of job templates.

GitHub Pipeline

  • UpdateVersionBranch prepared this branch automatically but could not push it: the run's GITHUB_TOKEN is refused when a commit creates or updates a file under .github/workflows/, and no permissions: key can grant that scope.

    ! [remote rejected] HEAD -> update/r8 (refusing to allow a GitHub App to create or
      update workflow `.github/workflows/CompletePipeline.yml` without `workflows` permission)
    

    The branch was therefore pushed with an installation token of the pytooling-claude GitHub App, which does carry that permission. The content is identical to what the job computed.


Related Issues and Pull-Requests

  • Follows v8.1.0 #264 (v8.1.0).
  • UpdateVersionBranch.yml needs a token with workflow write access to do this by itself; every repository whose version branch contains workflow files is affected, not only this one.

claude-code and others added 30 commits September 8, 2026 06:31
Both verification pipelines fail on every tag at *⤴ Publish Python wheel package to PyPI* -
`_Checking_SimplePackage_Pipeline.yml` and `_Checking_NamespacePackage_Pipeline.yml`, on v7.14.1 and
again on v7.15.0. `myPackage` and `myFramework.Extension` are fixtures that exist to exercise the job
templates; nobody publishes them. The failure only appears on tags, which is exactly the run someone
checks before cutting a release.

`PublishOnPyPI.yml` gains a `dry_run` input. When enabled, the two `twine upload` steps are replaced
by a single `twine check dist/*.whl dist/*.tar.gz`. Everything before them is unchanged, so the
artifact download, the Python setup and the dependency install are still exercised, and the package
metadata is validated rather than merely built.

`CompletePipeline.yml` forwards it as `pypi_dry_run`, defaulting to `'false'` so no consumer changes
behaviour.

Skipping the job entirely - an input that drops `PublishOnPyPI` from the pipeline - was the
alternative. It would leave the job template unverified, which is what the verification pipelines
exist to prevent, so a dry run that still reaches the packages was preferred.

Setting `pypi_dry_run: 'true'` in the two verification pipelines is deliberately *not* part of this
commit. They call `CompletePipeline.yml@dev`, so an input that exists only on this branch makes
GitHub reject the workflow file before a runner is assigned - "This run likely failed because of a
workflow file issue". The switch is flipped in a follow-up once this input is on `dev`.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…lates.

Both were written as local reusable workflows in 'pyTooling/SynchronizeForks' and have run there through two
releases; they are generic and belong here.

'UpdateVersionBranch' proposes the update of a major-version branch as a pull-request, titled like
'Updating r8 from v8.1.0'. A major without a branch is created from the highest existing lower major rather than
from the main branch - a branch cut from the main branch is already identical to it, so there would be nothing to
open a pull-request about. References to the repository itself are rewritten to name the version branch; where a
rewrite is needed it becomes a commit on an update branch, and the pull-request is opened from there.

'CheckMarketplaceMetadata' validates an action's metadata file against the GitHub Marketplace rules on every
push, instead of discovering a violation in the publish form. Publishing itself has no API and stays manual.

The 'workflow_dispatch' trigger both carried in their original repository is dropped: no job template here has
one.

Neither is wired into this repository's own checking workflows. 'UpdateVersionBranch' creates branches and
pull-requests, and 'CheckMarketplaceMetadata' would fail here by design, because this repository has no
'action.yml' at its root.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Taking the template into 'pyTooling/download-artifact' and 'pyTooling/upload-artifact' showed the assumption was
too narrow: both tag releases as 'v1.x.y' while publishing 'v4' ... 'v8' branches, so the branch number is not the
released version's major and deriving it would target 'v1'.

The optional 'major' parameter states it. Empty, the behaviour is unchanged.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
* The check is written in Python via 'shell: python' instead of a shell script with an embedded Python fragment.
  The step reads YAML and validates five rules, which is what Python is for; the metadata is parsed with
  'ruamel.yaml', installed after 'actions/setup-python', and a new 'python_version' parameter selects the
  interpreter.
* 'ubuntu_image' is the first input parameter in both templates and in both documentation pages, matching the
  other job templates.
* The instantiation example names its job 'CheckMarketplace' rather than 'Marketplace', so the instance says
  which template it is.
* One empty line before 'outputs:' in 'UpdateVersionBranch.yml', and its environment block is aligned again -
  'MAIN_BRANCH' had pushed the column.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
`CompletePipeline.yml` guards `PublishToGitHubPages` on the ref, because the `github-pages`
environment rejects a deployment from a feature branch before a runner is assigned - one second, no
steps, no log - so every feature-branch pipeline showed a red job unrelated to its changes.

The guard was written as an allowlist of the two refs that had been observed to deploy: the default
branch and `dev`. On a tag push `github.ref_name` is the tag, so the job is **skipped** - silently,
on the release run, which is the run whose documentation matters most.

Tags are admitted by the environment. pyVHDLModel's v0.39.0 pipeline, still on `@r7`, deployed Pages
from `ref_name = v0.39.0`
(https://github.com/VHDL/pyVHDLModel/actions/runs/30951229155, job `PublishToGitHubPages` success).

`github.ref_type == 'tag'` is added to the condition. Feature branches are still blocked, which is
what the guard was for.

`documentation_steps` defaults to `'html pages'`, so all eleven repositories calling
`CompletePipeline.yml` publish Pages and all eleven would have lost their release-run documentation
on moving to `@r8`. None has moved yet.

`doc/Development.rst` gains the rule this came from: a condition gating a job on the ref is a
blocklist of the refs that cannot work, never an allowlist of the refs that have been seen to work -
an allowlist built from one observed rejection drops every ref that was never tried, and drops it by
skipping, which no pipeline reports.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
PrepareJob evaluates the new 'publish_pages_on' input into the 'publish_pages' output; CompletePipeline forwards
the input and gates 'PublishToGitHubPages' on that output instead of a hard-coded list of refs.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…ions'.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…lib'.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…tplotlib' as well.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…sed or doesn't match the code.

'VersionCheck' gates 'TriggerTaggedRelease', 'ReleasePage' and 'PublishOnPyPI' and fails instead of being skipped;
it compares with the new 'package_version' output of 'Parameters.yml'. The new 'CheckReleaseVersion.yml' asks PyPI
for an existing release ('check_pypi_duplicate'), and 'TagReleaseCommit.yml' refuses an existing tag or release page.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
'CheckReleaseVersion.yml' runs 'VersionCheck' (compare with 'PythonVersion', no 'packaging') and 'RegistryCheck'
(new input 'pypi_url', default 'https://pypi.org'; no 'r' prefix handling). 'CompletePipeline.yml' calls it once
instead of a local job, staying at 20 distinct reusable workflows. Inputs are inlined instead of passed through 'env:',
and 'TagReleaseCommit.yml' exports 'GH_TOKEN' like 'PrepareJob.yml' and 'PublishReleaseNotes.yml'.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…her than PyPI.

'PublishOnPyPI.yml' gains 'pypi_upload_url' (default 'https://upload.pypi.org/legacy/'), passed to 'twine upload
--repository-url'. 'CompletePipeline.yml' gains 'pypi_url', forwarded to 'CheckReleaseVersion.yml', and
'pypi_upload_url', forwarded to 'PublishOnPyPI.yml' - a registry's upload URL isn't its base URL.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
It only named the file in error messages. An empty 'package_version' now fails the check with one message, and
'Parameters.yml' already warns about a missing version file.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
…m through 'env:'.

The three steps read '${{ inputs.* }}', '${{ github.repository }}' and the previous steps' outputs directly, and export
'GH_TOKEN' in the script like 'PrepareJob.yml' and 'PublishReleaseNotes.yml'. A shell variable remains only where the
value is changed: the version without its prefix and the escaped repository name.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
'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>
…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>
'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 and others added 7 commits September 16, 2026 22:41
'Release.yml' had 'claude/actions-pipeline' in its push trigger so the gate
could run before the workflow was on 'main'. It is on 'main' now, and the
branch is gone, so the trigger is 'main' alone again.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Every consumer's main workflow is 'Pipeline.yml' with 'name: Pipeline', and
the workflows this repository checks itself with are prefixed '_Checking_'.
This one is the repository's pipeline, so it takes that name.

'Prepare' and 'Verifications' are useful on any branch: they report in one
job whether the five verification workflows of a commit succeeded, which is
otherwise five runs to read. The push trigger is no longer limited to 'main'.
The release jobs need no new condition - 'is_release_commit' is only true for
a merge commit on the main branch, 'is_release_tag' only at a tag, and
'TriggerTaggedRelease' compares the ref a second time. A branch run skips all
three, as observed on 'claude/actions-pipeline'.

'TagReleaseCommit.yml' defaults its 'workflow' input to 'Pipeline.yml', so the
explicit input is gone with the rename.

Branch runs now cancel their predecessor: a branch only needs the roll-up of
its newest commit, and 'Verifications' occupies a runner until the checks it
waits for finish. 'main' and tags keep the old behaviour.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
The PDF build died in the first table of the document with

    ./myPackage.tex:1260: TeX capacity exceeded, sorry [input stack size=10000].
    <inserted text>          \the \everycr
    l.1260 \end{tabulary}

Sphinx' default 'latex_table_style' is ['booktabs', 'colorrows']. For
'colorrows' it sets colortbl's '\CT@everycr' to the token list '\the\everycr',
while colortbl sets '\everycr' to '\the\CT@everycr': each expands into the
other until TeX's input stack is full. colortbl is 2026/05/01 v1.0l.

The 56 "undefined reference" warnings in that job were a consequence - lualatex
returned 1, latexmk stopped, and nothing resolved the references on a second
pass.

Checked with MiKTeX 26.5 installed locally, the same version the image uses:
the document builds to 275 pages with no capacity error. Tables lose their
alternating row colors and keep the booktabs rules.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
The default release-notes footer credited 'pyTooling/Actions::Release.yml'.
That file was renamed to 'Pipeline.yml', but naming it there would be wrong
either way: the footer appears on a **consumer's** release page, and what
wrote it is the 'PublishReleaseNotes.yml' job template, not this repository's
own pipeline.

The documentation copy of the default is updated with it.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
@codacy-production

Copy link
Copy Markdown

Not up to standards ⛔

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.

@Paebbels
Paebbels merged commit 7b6ba66 into r8 Sep 17, 2026
32 of 35 checks passed
@Paebbels
Paebbels deleted the update/r8 branch September 17, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants