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
11 changes: 11 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## Summary
<!-- What does this PR do? -->

## Why
<!-- Why is this change needed? -->

## Version impact
- [ ] None
- [ ] Patch
- [ ] Minor
- [ ] Major
9 changes: 8 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ docs/ ← architecture.md, design.md, skills.md, workflow.md, roadmap
```

*Hand-authored exceptions in `.github/`: `copilot-instructions.md`, `CODEOWNERS`,
`pull_request_template.md`, `ISSUE_TEMPLATE/`, `workflows/`.
`PULL_REQUEST_TEMPLATE/`, `ISSUE_TEMPLATE/`, `workflows/`.

Generated files are written to `.github/` at install time:

Expand Down Expand Up @@ -132,6 +132,13 @@ For Python modules in this repository, treat code as the source of truth and kee
- Default to microservices and libraries unless UI is explicitly present.
- After each change: summary + files changed + how to test.

## Pull Request Response Format

- When asked to provide PR content, strictly follow the repository template at `.github/PULL_REQUEST_TEMPLATE/pull_request_template.md`.
- Always provide PR content in English.
- Always provide PR content as copy-paste-ready Markdown in a fenced `markdown` code block.
- Do not add extra sections that are not present in the active PR template.

## Context Exclusions

When searching or reading repository content, ignore generated and third-party directories by default:
Expand Down
20 changes: 0 additions & 20 deletions .github/pull_request_template.md

This file was deleted.

5 changes: 5 additions & 0 deletions .github/workflows/commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ on:
- merge/**
- gh-readonly-queue/**

concurrency:
# Cancel superseded commit-message checks on the same branch.
group: commit-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
# Read-only is enough for commit metadata checks.
contents: read
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
push:
branches-ignore: [main]

concurrency:
# Cancel superseded QA runs for the same branch.
group: qa-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
# Workflow only needs read access to repository contents.
contents: read
Expand Down
90 changes: 67 additions & 23 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ on:
push:
branches: [main]

concurrency:
# Serialize main releases to avoid concurrent tag/release races.
group: release-${{ github.ref }}
cancel-in-progress: false

permissions:
# Default to read-only; release job elevates to write for tagging/releases.
contents: read
Expand All @@ -22,8 +27,7 @@ env:

jobs:
release:
# Computes semantic version from conventional commits, creates git tag,
# and publishes GitHub release.
# Computes semantic version from conventional commits and creates git tag.
name: Compute Version and Tag
runs-on: ubuntu-latest
permissions:
Expand Down Expand Up @@ -88,26 +92,13 @@ jobs:
}
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git rev-parse "$VERSION" >/dev/null 2>&1 && {
git show-ref --verify --quiet "refs/tags/$VERSION" && {
echo "ERROR: tag '$VERSION' already exists.";
exit 1;
}
git tag -a "$VERSION" -m "release $VERSION"
git push origin "$VERSION"

Comment thread
eschaar marked this conversation as resolved.
- name: Compute release date
if: steps.version.outputs.changed == 'true'
id: release_date
run: echo "date=$(date -u +%Y-%m-%d)" >> "$GITHUB_OUTPUT"

- name: Create GitHub release
if: steps.version.outputs.changed == 'true'
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ steps.version.outputs.version }}
name: Release v${{ steps.version.outputs.version }} (${{ steps.release_date.outputs.date }})
generate_release_notes: true

build:
# Build distributions only when semver-action reports a new release.
name: Build Package Artifacts
Expand All @@ -121,16 +112,13 @@ jobs:
with:
# Build from the newly created release tag to guarantee package version.
ref: refs/tags/${{ needs.release.outputs.version }}
fetch-depth: 1
fetch-tags: true
fetch-depth: 0

- name: Install Poetry
run: |
pipx install "poetry==${POETRY_VERSION}"
pipx inject poetry "poetry-dynamic-versioning[plugin]>=1.0.0,<2.0.0"
run: pipx install "poetry==${POETRY_VERSION}"

- name: Show Poetry plugins
run: poetry self show plugins
- name: Install poetry-dynamic-versioning plugin
run: pipx inject poetry "poetry-dynamic-versioning[plugin]>=1.0.0,<2.0.0"

- name: Setup Python
uses: actions/setup-python@v6
Expand All @@ -150,9 +138,21 @@ jobs:
exit 1
fi

- name: Show active Poetry plugins
run: poetry self show plugins

- name: Apply dynamic version
run: poetry dynamic-versioning

- name: Build distributions
run: poetry build

- name: Smoke test built wheel
run: |
python -m pip install --upgrade pip
python -m pip install --no-deps dist/*.whl
vstack --help >/dev/null

- name: Validate built artifact version
run: |
EXPECTED="${{ needs.release.outputs.version }}"
Expand Down Expand Up @@ -191,3 +191,47 @@ jobs:

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

cleanup-failed-release-tag:
# Delete freshly created release tag when downstream jobs fail.
name: Cleanup Failed Release Tag
runs-on: ubuntu-latest
needs: [release, build, publish]
if: ${{ always() && needs.release.outputs.changed == 'true' && (needs.build.result == 'failure' || needs.publish.result == 'failure') }}
permissions:
contents: write

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Delete failed release tag
run: |
VERSION="${{ needs.release.outputs.version }}"
if git ls-remote --exit-code --tags origin "refs/tags/$VERSION" >/dev/null; then
git push origin ":refs/tags/$VERSION"
echo "Deleted failed release tag '$VERSION' from origin."
else
echo "Tag '$VERSION' already absent; nothing to delete."
fi

github-release:
# Create GitHub Release only after package build and publish succeed.
name: Publish GitHub Release
runs-on: ubuntu-latest
needs: [release, publish]
if: needs.release.outputs.changed == 'true'
permissions:
contents: write

steps:
- name: Compute release date
id: release_date
run: echo "date=$(date -u +%Y-%m-%d)" >> "$GITHUB_OUTPUT"

- name: Create GitHub release
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ needs.release.outputs.version }}
name: Release v${{ needs.release.outputs.version }} (${{ steps.release_date.outputs.date }})
generate_release_notes: true
5 changes: 5 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:
pull_request:
branches: [main]

concurrency:
# Cancel superseded security scans for the same PR.
group: security-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
# Required by checkout and PR-context scanners.
contents: read
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:
pull_request:
branches: [main]

concurrency:
# Cancel superseded verification runs for the same PR.
group: verify-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
# Verify jobs only read repository contents.
contents: read
Expand Down
21 changes: 17 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
# Changelog

## 1.3.4 - 2026-04-22

Release build versioning fix: explicit plugin activation and full history checkout.

### Fixed in 1.3.4

- Fixed CI release builds still producing `0.0.0` artifacts by calling `poetry dynamic-versioning` explicitly before `poetry build`. Poetry reads the version once at load time — the plugin must be active and called before the build step runs.
- Fixed release build tag visibility by setting `fetch-depth: 0` on the tag-pinned checkout so `git describe` can traverse full history.
- Fixed release race conditions by adding workflow `concurrency` controls, including serialized main release execution.
- Fixed release integrity by creating the GitHub release only after PyPI publish succeeds.
- Fixed tag existence validation to check `refs/tags/<version>` directly instead of a generic ref lookup.
- Fixed rerun friction after failed release attempts by automatically deleting the freshly created tag when build or publish fails.
- Added post-build wheel smoke test (`pip install --no-deps` + `vstack --help`) before artifact upload to avoid network-dependent dependency resolution.
- Clarified PR workflow concurrency comments in `security.yml` and `verify.yml` to match `github.ref` behavior (`refs/pull/<id>/merge`).

## 1.3.3 - 2026-04-22

Release build plugin activation fix.

### Fixed in 1.3.3

- Fixed CI release builds producing `0.0.0` artifacts by installing/enabling `poetry-dynamic-versioning` in the Poetry runtime used by the build job.
- Fixed release build reproducibility by pinning the Poetry CLI version in workflow environment configuration.
- Fixed CI release builds producing `0.0.0` artifacts by installing `poetry-dynamic-versioning` as a Poetry plugin via `pipx inject` in the release build job.
- Fixed release build reproducibility by pinning the Poetry CLI version (`POETRY_VERSION`) in workflow environment configuration.
- Fixed CI drift by aligning Poetry installation to the same pinned version across `release.yml`, `qa.yml`, `verify.yml`, and `security.yml`.
- Fixed release workflow noise by inlining SemVer format validation into the tag creation step.
- Added Poetry plugin visibility in release logs via `poetry self show plugins` to simplify troubleshooting.

## 1.3.2 - 2026-04-22

Expand Down
Loading