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
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: VERSION holds a single vX.Y.Z version
- name: VERSION holds a single X.Y.Z version
run: |
grep -Eqx 'v[0-9]+\.[0-9]+\.[0-9]+' VERSION && [ "$(grep -c "" VERSION)" -eq 1 ] || {
echo "::error file=VERSION::VERSION must be one line of the form vX.Y.Z"
grep -Eqx '[0-9]+\.[0-9]+\.[0-9]+' VERSION && [ "$(grep -c "" VERSION)" -eq 1 ] || {
echo "::error file=VERSION::VERSION must be one line of the form X.Y.Z, without a leading v"
exit 1
}

Expand All @@ -41,7 +41,7 @@ jobs:
with:
persist-credentials: false
- id: version
run: echo "tag=$(tr -d "[:space:]" < VERSION)" >> "$GITHUB_OUTPUT"
run: echo "tag=v$(tr -d "[:space:]" < VERSION)" >> "$GITHUB_OUTPUT"
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
TAG: ${{ steps.version.outputs.tag }}
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
* fix/devcontainer-timezone: the dev container, and CI with it, starts on hosts that have no /etc/timezone.
* fix/bash-history-mount: shell history in the dev container persists between sessions.
* feature/version-file: generated projects take their package version from VERSION; existing projects run `uv lock` once after updating.
* feature/plain-version: VERSION holds a plain X.Y.Z here and in generated projects, with CI adding the v for tags; existing projects remove the v from VERSION once.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ Projects generated before the answers file moved keep it in `.copier-generic-pro
$ git mv .copier-generic-project/.copier-py-answers.yml .copier-py-answers.yml
```

Projects generated before 3.0.0 hold `vX.Y.Z` in `VERSION`. Remove the leading `v` once when updating, or the shared CI's version check fails:

```bash
$ sed -i 's/^v//' VERSION
```

Projects generated before v2.2.0 hold a fixed version in `uv.lock`. After the update that takes `pyproject.toml` to the version in `VERSION`, refresh the lock once and commit it, or `make build` fails on the out-of-date lock:

```bash
Expand All @@ -61,14 +67,14 @@ $ uv lock

### Versioning and CI

The template's release version lives in `VERSION` as `vX.Y.Z`. Bump it in every change that should be released:
The template's release version lives in `VERSION` as a plain `X.Y.Z`, without a leading `v`. Bump it in every change that should be released:
* `Z` for minor fixes.
* `Y` for minor features and chores.
* `X` for breaking changes, such as renamed questions or moved files that affect `copier update` in existing projects.

GitHub Actions (`.github/workflows/ci.yml`) runs two jobs:
* **version:** on every pull request and push to `main`, checks that `VERSION` holds a single `vX.Y.Z` line.
* **tag:** on push to `main`, tags the merged commit with the version in `VERSION`, so existing projects can move to it with `copier update`. If the tag already exists, nothing is tagged.
* **version:** on every pull request and push to `main`, checks that `VERSION` holds a single `X.Y.Z` line.
* **tag:** on push to `main`, tags the merged commit `v` plus the version in `VERSION`, such as `v1.2.3`, so existing projects can move to it with `copier update`. If the tag already exists, nothing is tagged.

The workflow is read-only apart from the tag job, which needs write access to create the tag. It runs on `pull_request`, never `pull_request_target`, so code from a fork never runs with this repository's credentials. Actions are pinned to commit SHAs, and Renovate (`renovate.json`) proposes updates to them weekly.

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v2.2.0
3.0.0
2 changes: 1 addition & 1 deletion template/.github/.copier-ci-answers.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# .github/.copier-ci-answers.yml.jinja
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
_commit: v2.0.0
_commit: v3.0.0
_src_path: gh:karshosphere/template-github-ci
13 changes: 7 additions & 6 deletions template/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,21 @@ jobs:
persist-credentials: false
# full history, so every existing release tag is available to compare against
fetch-depth: 0
- name: VERSION holds a single vX.Y.Z version
- name: VERSION holds a single X.Y.Z version
run: |
if ! grep -Eqx 'v[0-9]+\.[0-9]+\.[0-9]+' VERSION || [ "$(grep -c "" VERSION)" -ne 1 ]; then
echo "::error file=VERSION::VERSION must be one line of the form vX.Y.Z"
if ! grep -Eqx '[0-9]+\.[0-9]+\.[0-9]+' VERSION || [ "$(grep -c "" VERSION)" -ne 1 ]; then
echo "::error file=VERSION::VERSION must be one line of the form X.Y.Z, without a leading v"
exit 1
fi
- name: VERSION is higher than every release tag
run: |
version=$(tr -d '[:space:]' < VERSION)
# release tags are the version with a leading v
version=v$(tr -d '[:space:]' < VERSION)
latest=$(git tag --list --sort=-v:refname | { grep -Ex 'v[0-9]+\.[0-9]+\.[0-9]+' || true; } | sed -n 1p)
if [ -n "$latest" ]; then
highest=$(printf '%s\n' "$latest" "$version" | sort -V | tail -n 1)
if [ "$version" = "$latest" ] || [ "$highest" != "$version" ]; then
echo "::error file=VERSION::VERSION is $version but $latest is already released; bump it above $latest"
echo "::error file=VERSION::VERSION is ${version#v} but $latest is already released; bump it above ${latest#v}"
exit 1
fi
fi
Expand Down Expand Up @@ -96,7 +97,7 @@ jobs:
with:
persist-credentials: false
- id: version
run: echo "tag=$(tr -d "[:space:]" < VERSION)" >> "$GITHUB_OUTPUT"
run: echo "tag=v$(tr -d "[:space:]" < VERSION)" >> "$GITHUB_OUTPUT"
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
with:
# a pattern rather than a name, so a missing artifact means no files instead of a failure
Expand Down
2 changes: 1 addition & 1 deletion template/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.1.0
0.1.0
2 changes: 1 addition & 1 deletion template/pyproject.toml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ dependencies = [
[project.scripts]
main = "{{ module_slug }}.main:main"

# setuptools reads VERSION, the version CI releases, and drops the leading v
# setuptools reads VERSION, the version CI releases
[tool.setuptools.dynamic]
version = { file = "VERSION" }

Expand Down