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
41 changes: 41 additions & 0 deletions .github/workflows/bump-v1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,47 @@ jobs:
print(f"changelog documents {version}, and [Unreleased] is empty")
PY

# Runs after every refusal above, so a release that is going to be turned
# away never has its tag rewritten.
- name: Annotate the release tag
env:
GH_TOKEN: ${{ github.token }}
RELEASE_SHA: ${{ github.sha }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
run: |
set -euo pipefail
# The Move step below puts v1 on this same commit, and copier reads a
# template's version through dunamai, which takes the commit's newest
# tag by date. An annotated tag's date is when it was tagged; a
# lightweight tag's is its commit's. With both lightweight they tie on
# date and dunamai breaks the tie by name, which picks "v1". Copier
# then parses that as version 1 and records `_commit: v1` in every
# consumer's .copier-answers.yml, and a consumer above 1.0.0 can fail
# `copier update` with "Downgrades are not supported".
#
# Publishing a release for a tag that does not exist yet -- the GitHub
# UI's default, and `gh release create` without --verify-tag -- makes
# that tag lightweight. Rather than refuse the release over it, give
# the tag an annotation here so it outranks v1 and copier reads
# "v1.2.0". Annotating v1 too would break it again: v1 is re-tagged on
# every release, so it would always be the newer of the two.
#
# The rewrite keeps the same target commit, and the release references
# the tag by name, so the published release is unaffected. It lands
# seconds after publication, before the tag has realistically been
# fetched anywhere.
type=$(gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/${RELEASE_TAG}" --jq .object.type)
if [ "$type" = "tag" ]; then
echo "${RELEASE_TAG} is already annotated"
exit 0
fi
tag_sha=$(gh api -X POST "repos/${GITHUB_REPOSITORY}/git/tags" \
-f tag="${RELEASE_TAG}" -f message="${RELEASE_TAG}" \
-f object="${RELEASE_SHA}" -f type=commit --jq .sha)
gh api -X PATCH "repos/${GITHUB_REPOSITORY}/git/refs/tags/${RELEASE_TAG}" \
-f sha="${tag_sha}" -F force=true
echo "${RELEASE_TAG} annotated as ${tag_sha} (still on ${RELEASE_SHA})"

- name: Move v1
env:
GH_TOKEN: ${{ github.token }}
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [Unreleased]

### Fixed

- `bump-v1.yml` annotates the release tag before moving `v1` onto the same
commit. With both tags lightweight, copier read the template's version as
`1`, so the weekly template update rewrote consumers' `_commit` to `v1`
instead of the release they were on. v1.1.0 shipped this way. Ported from
python-project-template 1.8.1.

### Added

- The README and the post-copy message name the repository setting the
template-update workflow needs: **Allow GitHub Actions to create and approve
pull requests**. Without it the run pushes its branch and fails to open the
PR.

## [1.1.0] - 2026-09-22

### Added
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ demand) and opens a PR when the template's *scaffolded files* have changed.
Reusable-workflow changes need no update run: consumers pin `@v1`, so moving
the tag propagates those immediately.

The workflow opens its PR with the default `GITHUB_TOKEN`, which needs
*Settings → Actions → General →* **Allow GitHub Actions to create and approve
pull requests** turned on. Without it the run pushes `chore/template-update`
and then fails with `GitHub Actions is not permitted to create or approve pull
requests`.

## Adopt the template in an existing Worker repo

`copier update` needs a `.copier-answers.yml` recording which template
Expand Down
6 changes: 6 additions & 0 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ _message_after_copy: |
Routes Write on the zone) and CLOUDFLARE_ACCOUNT_ID as repository secrets.
Editor cannot create a Worker, so do the FIRST deploy by hand:
npx wrangler login && npm run deploy
{% if use_template_update %}

The weekly template-update workflow opens its PR with the default token:
turn on Settings > Actions > General > "Allow GitHub Actions to create and
approve pull requests".
{% endif %}

project_name:
type: str
Expand Down
Loading