Skip to content

v7.14.0 - #240

Merged
Paebbels merged 8 commits into
mainfrom
dev
Jul 31, 2026
Merged

v7.14.0#240
Paebbels merged 8 commits into
mainfrom
dev

Conversation

@Paebbels

Copy link
Copy Markdown
Member

New Features

  • CleanupArtifacts.yml gained condition and condition2. Two boolean inputs, defaulting to true, placed between each JSON dictionary and its id list:

    jsonconditionartifact-json-ids first set
    json2condition2artifact-json-ids2 second set

    Each is wired into the if: of both its compute and its delete step, so a disabled set neither resolves names nor deletes anything. Existing callers are unaffected — the default preserves today's behaviour.

Bug Fixes

  • The package artifact could be deleted while PublishOnPyPI was using it. In CompletePipeline.yml, ArtifactCleanUp listed package_all in the unconditional set, while its needs: has # - PublishOnPyPI commented out — so on a release-tag run the cleanup and the upload ran concurrently, and the wheel could vanish from under the publish job.

    package_all now moves to the guarded second set:

          condition2: ${{ ! startsWith(github.ref, 'refs/tags') }}
          artifact-json-ids2: >-
            package_all

    which is the same guard ArtifactCleanUp.yml has always had. On a tagged run PublishOnPyPI consumes the artifact and deletes it itself.

    The window is real and measured — pyTooling v8.19.0 (run 30612877620): cleanup ran 07:34:2807:34:40, publish started 07:34:58. That release survived only because pyTooling/pyTooling doesn't use CompletePipeline.yml; it calls the older ArtifactCleanUp.yml, whose guard kept pyTooling-Packages out of the deleted list.

  • VersionCheck rejected every prefixed tag. Prepare.outputs.version is derived from the tag and may carry a v/r prefix, while extractVersionInformation(...).Version is a plain str that never does — so the string comparison could never succeed for a repository tagging vX.Y.Z:

    expected:  v0.38.0
    from code: 0.38.0
    ##[error]Expected version (v0.38.0) doesn't match the version in Python code (0.38.0).
    

    Hit by VHDL/pyVHDLModel v0.38.0 and pyTooling/sphinx-reports v0.11.2, and not workaroundable by a consumer. Both sides are now parsed with SemanticVersion, which ignores the prefix; a parse failure is reported as an error instead of crashing the step.

Changes

  • ArtifactCleanUp.yml now emits a deprecation warning. A ::warning annotation plus a migration note in the job log: packagejson2 + artifact-json-ids2 guarded by condition2; remainingjson + artifact-json-ids, or others for literal names. Slated for removal in r8.

    The message deliberately avoids literal ${{ }} braces — Actions substitutes those inside run: blocks before the shell sees them, so an example containing them would be evaluated rather than printed.

Unit Tests

  • _Checking_CleanupArtifacts.yml moves package_all into the guarded second set, exercising condition2.
  • _Checking_JobTemplates.yml already binds both sets to two different name dictionaries (UnitTestingParams and PlatformTestingParams), so there was no free slot. The package artifact gets its own PackageArtifactCleanUp job using condition, which exercises the first-set guard and removes the same race from that pipeline — it has a PublishOnPyPI job too.

Verification

Version comparison, checked on pyTooling 8.17.0 and 8.19.0 — both the cases that must pass and the cases that must still fail:

expected (from tag) in code equal wanted
v0.11.2 0.11.2
v0.38.0 0.38.0
v8.19.0 8.19.0
r7.13.1 7.13.1
0.11.2 0.11.2
v0.11.2 0.11.1
v1.0.0 0.11.2

All five changed workflows parse as YAML with balanced ${{ }} expressions, and the deprecation script was executed to confirm its rendered output.


Related Issues and Pull-Requests

Note

The documentation is not updated in this release. CleanupArtifacts.yml has no documentation page at all — the documented ArtifactCleanup.rst covers the deprecated workflow — and the instantiation examples are still on @r6. Tracked separately; it needs a rework rather than a patch.

claude-code and others added 5 commits July 28, 2026 22:50
The job template pipeline verified every template except ApplicationTesting.
Added AppTestingParams and AppTesting using the same wiring as
CompletePipeline: AppTesting depends on ConfigParams, AppTestingParams,
UnitTestingParams and Package, reuses the wheel and the 'apptesting_xml'
artifact name of UnitTestingParams, and feeds PublishTestResults.

PublishTestResults now merges the application test results too
(reduce-depth:pytest.tests.app) and uses '!cancelled()', so a skipped or
failing AppTesting no longer takes the report - and the chain behind it -
down with it.

Reduced the pipeline matrices to cut queueing time. Windows, macOS and
MSYS2 runners are limited and dominate the wall time, so both pipelines
now run on 'ubuntu ubuntu-arm' only. SimplePackage tests Python 3.14 and
NamespacePackage tests Python 3.11, so together they still cover both
ends of the supported range.

Generated with the workflow's own matrix generator:
* SimplePackage unit tests:    31 -> 2 jobs
* NamespacePackage unit tests: 31 -> 2 jobs
* SimplePackage app tests:      7 -> 2 jobs
* new AppTesting in JobTemplates:    2 jobs

Bumped the fixture packages from 7.13.1 to 7.14.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The variable summary printed package_directory instead of
package_version_file, so the log showed e.g. 'myPackage' where
'myPackage/__init__.py' was meant. Only the message was wrong; the job
output itself always used the correct variable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* AppTesting in the job template verification now uses the default system
  list, so all systems are tested with one Python version (2 -> 8 jobs).
* Moved the matrix comments onto the value line they describe.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… comparison

**`CleanupArtifacts.yml`: `condition` and `condition2`**

Two boolean inputs, defaulting to `true`, placed between each JSON dictionary
and its id list: `condition` for the first set, `condition2` for the second.
Each is wired into the `if:` of both its compute *and* its delete step, so a
disabled set neither resolves names nor deletes anything. Existing callers are
unaffected.

**`CompletePipeline.yml`: the package artifact survives a tagged run**

`ArtifactCleanUp` listed `package_all` in the unconditional set while its
`needs:` has `#      - PublishOnPyPI` commented out, so on a release-tag run the
cleanup and the upload ran concurrently and the wheel could be deleted from
under `PublishOnPyPI`. It now moves to the second set with

    condition2: ${{ ! startsWith(github.ref, 'refs/tags') }}

which is the same guard `ArtifactCleanUp.yml` has always had. On a tagged run
`PublishOnPyPI` consumes the artifact and deletes it itself.

Measured window on pyTooling v8.19.0 (run 30612877620): cleanup 07:34:28-07:34:40,
publish started 07:34:58. That release survived only because pyTooling doesn't use
`CompletePipeline.yml`.

**`CompletePipeline.yml`: `VersionCheck` accepts a tag prefix**

`Prepare.outputs.version` comes from the tag and may carry a `v`/`r` prefix,
while `extractVersionInformation(...).Version` is a plain `str` that never does,
so the string comparison failed for every prefixed-tag repository - pyVHDLModel
v0.38.0 and sphinx-reports v0.11.2 both hit it. Both sides are now parsed with
`SemanticVersion`, which ignores the prefix, with a parse failure reported as an
error rather than crashing the step.

Checked on pyTooling 8.17.0 and 8.19.0: `v0.11.2`/`0.11.2`, `v0.38.0`/`0.38.0`,
`v8.19.0`/`8.19.0`, `r7.13.1`/`7.13.1` and `0.11.2`/`0.11.2` all compare equal,
while `v0.11.2`/`0.11.1` and `v1.0.0`/`0.11.2` still fail as they must.

**`ArtifactCleanUp.yml`: deprecation warning**

Emits a `::warning` annotation plus a migration note - `package` becomes
`json2`/`artifact-json-ids2` guarded by `condition2`, `remaining` becomes
`json`/`artifact-json-ids` or `others`. Removed in r8. The message avoids literal
expression braces, since Actions substitutes those inside `run:` blocks.

**Test pipelines**

`_Checking_CleanupArtifacts.yml` moves `package_all` into the guarded second set.
`_Checking_JobTemplates.yml` already binds both sets to two different name
dictionaries, so the package artifact gets its own `PackageArtifactCleanUp` job
using `condition` - which exercises the first-set guard and removes the same race
from that pipeline, since it has a `PublishOnPyPI` job too.

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

codacy-production Bot commented Jul 31, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

🟢 Coverage 100.00% diff coverage · +0.00% coverage variation

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

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (cc2d764) 45 41 91.11%
Head commit (9864288) 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 (#240) 1 1 100.00%

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.

@Paebbels

Copy link
Copy Markdown
Member Author

CI on dev @ 6ef7f1d

The changed jobs all pass. The three remaining failures are pre-existing or external — verified against the previous commit (8abd070) rather than assumed.

What the change exercises

Job Pipeline Result
NamespacePackage / ArtifactCleanUp CompletePipeline.yml with package_all in the new guarded set ✅ success
PackageArtifactCleanUp new job in _Checking_JobTemplates.yml, exercising condition ✅ success
IntermediateCleanUp unchanged caller, proves the default condition: true is non-breaking ✅ success
SimplePackage / ArtifactCleanUp skipped — that pipeline sets cleanup: 'false'

Worth noting: in the Job Templates run the old ArtifactCleanUp was skipped because a dependency failed, while PackageArtifactCleanUp still ran — it carries if: ${{ !cancelled() }}. The new job is the more robust of the two.

The three failures

1 & 2. Documentation (HTML and LaTeX), in both package pipelines. Same cause, confirmed in the logs:

NameError: name 'ResultCollection' is not defined

This is the sphinx_reports 0.11.1pyEDAA.Reports ~= 0.17.4 pin, fixed in pyEDAA.Reports v0.18.0 but unreachable until sphinx-reports#99 (v0.11.2) is released. Identical to what blocks VHDL/pyVHDLModel#167.

It's newly visible rather than newly caused: on 8abd070 these pipelines died earlier, at Prepare / Extract Information, which masked the documentation step.

3. CodeQuality / 🩺 Linting. Already failing on 8abd070 — both in Simple Package and Job Templates. Untouched by this PR.

Baseline comparison (8abd070)

Verification of Job Templates          -> failure  (Prepare, Linting, PDFDocumentation)
Verification of Pipeline Templates (Simple Package)    -> failure  (Prepare, Linting)
Verification of Pipeline Templates (Namespace Package) -> failure  (Prepare)
Verification Pipeline for Parameters   -> success
Testing available GitHub Action Images -> success

So Prepare / Extract Information now passes where it used to fail, and no new failure category appears.

artifact: ${{ fromJson(needs.UnitTestingParams.outputs.artifact_names).package_all }}
secrets: inherit

PackageArtifactCleanUp:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a new job? you could use condition2 in ArtifactCleanUp.

the implementation of condition and condition2 is identical no need to test them independently.

Comment thread .github/workflows/CompletePipeline.yml Outdated
#documentation_latex
#documentation_pdf
json2: ${{ needs.UnitTestingParams.outputs.artifact_names }}
condition2: ${{ ! startsWith(github.ref, 'refs/tags') }} # on a tagged run, 'PublishOnPyPI' consumes the package artifact and deletes it itself

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why such a low-level condition? Why not the inverse of needs.Prepare.outputs.is_release_tag used by PublishOnPyPI?

Two review comments on #240.

**`condition2` keys off the same flag as `PublishOnPyPI`**

`${{ ! startsWith(github.ref, 'refs/tags') }}` was the low-level proxy inherited
from `ArtifactCleanUp.yml`. `needs.Prepare.outputs.is_release_tag` is what
`PublishOnPyPI` and `ReleasePage` already gate on, so keying the cleanup off its
inverse makes producer and consumer agree by construction instead of by two
expressions that happen to coincide. It is also more precise: a non-release tag
no longer leaves the package artifact behind forever.

`Prepare` is added to the `needs:` of `ArtifactCleanUp` in both pipelines, since
the flag is only reachable through it.

**One cleanup job, not two**

`condition` and `condition2` are the same implementation, so testing them
separately buys nothing. The extra `PackageArtifactCleanUp` job is gone and
`_Checking_JobTemplates.yml` uses `condition2` in its own `ArtifactCleanUp`, as
`CompletePipeline.yml` does.

That needed the second JSON slot, which was bound to the platform-testing names.
Those move to the `others` input, spelled literally - which exercises `others`
as a side effect. All three groups are still cleaned: unit-testing artifacts and
platform artifacts unconditionally, the package artifact only off a release tag.

The deprecation hint in `ArtifactCleanUp.yml` now points at `is_release_tag`
too, rather than the `startsWith` form.

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

Copy link
Copy Markdown
Member Author

Both applied in e67efd5.

is_release_tag instead of the startsWith proxy. Agreed, and it is better than a tidy-up: keying the cleanup off the inverse of the flag PublishOnPyPI and ReleasePage already gate on makes producer and consumer agree by construction, rather than by two expressions that happen to coincide. It is also more precise — with the github.ref proxy a non-release tag would have kept the package artifact forever. Prepare is added to the needs: of ArtifactCleanUp in both pipelines, since the flag is only reachable through it.

One job, not two. You are right that the two implementations are identical, so testing them separately buys nothing — PackageArtifactCleanUp is gone.

One thing worth flagging, since it is why I had reached for a second job: _Checking_JobTemplates.yml had both JSON slots occupied — json for UnitTestingParams and json2 for PlatformTestingParams — while it needs three groups with two different conditions (unit-testing artifacts unconditional, platform artifacts unconditional, package artifact only off a release tag). To free json2 for the package, the platform names moved to the others input, spelled literally. That works and exercises others as a bonus, and all three groups are still cleaned.

It does mean two guarded sets is the ceiling: a caller needing a third has to fall back to others (unguarded) or a second job. Fine here; worth knowing if a future template wants more, and a candidate for r8 if the inputs ever become a list.

The deprecation hint in ArtifactCleanUp.yml now points at is_release_tag as well.

claude-code and others added 2 commits July 31, 2026 21:42
`_Checking_JobTemplates.yml`'s `ArtifactCleanUp` carried no `if:`, so a failed
dependency skipped it. With the currently-red `Documentation` jobs that meant the
restructured cleanup - the thing this PR changes - never executed in that
pipeline, and its artifacts leaked on every failed run.

Guarded with `!cancelled()`, matching what `CompletePipeline.yml` already does
for the same job.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
Two review comments on #240.

**`condition2` keys off the same flag as `PublishOnPyPI`**

`${{ ! startsWith(github.ref, 'refs/tags') }}` was the low-level proxy inherited
from `ArtifactCleanUp.yml`. `needs.Prepare.outputs.is_release_tag` is what
`PublishOnPyPI` and `ReleasePage` already gate on, so keying the cleanup off its
inverse makes producer and consumer agree by construction instead of by two
expressions that happen to coincide. It is also more precise: a non-release tag
no longer leaves the package artifact behind forever.

`Prepare` is added to the `needs:` of `ArtifactCleanUp` in both pipelines, since
the flag is only reachable through it.

**One cleanup job, not two**

`condition` and `condition2` are the same implementation, so testing them
separately buys nothing. The extra `PackageArtifactCleanUp` job is gone and
`_Checking_JobTemplates.yml` uses `condition2` in its own `ArtifactCleanUp`, as
`CompletePipeline.yml` does.

That needed the second JSON slot, which was bound to the platform-testing names.
Those move to the `others` input, spelled literally - which exercises `others`
as a side effect. All three groups are still cleaned: unit-testing artifacts and
platform artifacts unconditionally, the package artifact only off a release tag.

The deprecation hint in `ArtifactCleanUp.yml` now points at `is_release_tag`
too, rather than the `startsWith` form.

Co-Authored-By: Patrick Lehmann <Paebbels@gmail.com>
@Paebbels
Paebbels merged commit ff250ba into main Jul 31, 2026
138 of 144 checks passed
This was referenced Jul 31, 2026
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