mirror of
https://github.com/harvard-edge/cs249r_book.git
synced 2026-05-06 17:49:07 -05:00
[PR #1408] [MERGED] PR-4b: Per-volume book versioning (vol1-v* / vol2-v* independent tag spaces) #6528
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/harvard-edge/cs249r_book/pull/1408
Author: @profvjreddi
Created: 4/19/2026
Status: ✅ Merged
Merged: 4/19/2026
Merged by: @profvjreddi
Base:
dev← Head:release-prep/book-versioning📝 Commits (1)
ed98b62feat(book-publish): per-volume versioning (vol1-v* / vol2-v* tags)📊 Changes
2 files changed (+218 additions, -102 deletions)
View changed files
📝
.github/workflows/book-publish-live.yml(+217 -101)📝
book/quarto/contents/vol2/index.qmd(+1 -1)📄 Description
Summary
Refactor
book-publish-live.ymlso Volume I and Volume II evolve onindependent semver lifecycles instead of sharing one
book-v*tagnamespace. Required so we can ship Volume II at v0.1.0 while Volume I
continues from v0.5.1 → v0.6.0 → ... without one volume's bump
implicitly relabeling the other.
Why now
Two real problems with the current workflow that block the staged
launch:
index.qmdfiles were stuck atdoi: \"v0.5.1\"(root + vol1 + vol2). The publish step only sed'd the root
index.qmd, so the per-volume Quarto title blocks displayed a stale
version after every release.
book-v*tag space couldn't represent twoindependently-versioned volumes — bumping for a Vol II content
change would have implied a Vol I release too, which is wrong.
What changed
.github/workflows/book-publish-live.yml:New per-volume outputs from
validate-inputs:new_vol1_version,new_vol2_version,previous_vol1_version,previous_vol2_version. The legacynew_version/previous_versionoutputs are retained as a backwards-compatiblesummary string (e.g.
vol1-v0.6.0+vol2-v0.1.0) for the ~50downstream references that just want a printable version label.
Calculate Next Versionstep rewritten with two helpers:bump <prefix> <prev_full_tag>— applies major/minor/patch tothe numeric portion. Each
localdeclaration is on its own line(bundled
local a=\$1 b=\$2 c=\${b#x}silently breaksc).latest_for <prefix> [fallback]— finds the latest<prefix>-v*tag, with a fallback for the very first release.Logic:
book-v*(so v0.5.1 → v0.6.0 lineis preserved across the rename). Subsequent bumps come from
vol1-v*tags.vol2-v0.0.0so the FIRST publish withrelease_type=minorlands atvol2-v0.1.0.deploy_targetinput (vol1/vol2/all) decideswhich volume(s) get bumped on a given run.
Update per-volume version in index.qmdstep now updatescontents/vol1/index.qmdand/orcontents/vol2/index.qmdbasedon
deploy_target. Strips thevolX-prefix when writing thedoi:field (readers see "v0.6.0", the tag is "vol1-v0.6.0").Legacy root
index.qmdis intentionally untouched — it's theunified landing, not a volume.
Create per-volume release tag(s)step createsvol1-v*and/or
vol2-v*tags independently. Refuses to overwrite anexisting tag (no
--force-with-leaseon a remote tag — that wouldsilently overwrite a previously-shipped release).
previous_versioninput description updated: whendeploy_target=all, the input is ignored and both versions areauto-detected; when targeting a single volume, the input applies
to that volume.
book/quarto/contents/vol2/index.qmd:doi: \"v0.1.0-pre\"to establish a clear pre-release baselinefor Volume II so the rendered title block stops claiming v0.5.1
before the workflow ever runs.
Risk surface
pages until a publish runs.
conflicting tag, the next publish will error with a clear message
and require manual intervention. This is intentional — the
alternative (silent overwrite) corrupts release history.
new_version/previous_versioncontinue to work; they just see a richer string.Verification
legacy
book-v*only, bothvol1-v*andvol2-v*present).python3 -c \"import yaml; yaml.safe_load(open('.github/workflows/book-publish-live.yml'))\"parses clean.book-publish-live.ymlwithdeploy_target=vol2,release_type=minorin TESTING MODE;observe the computed versions in the workflow logs (should be
vol2-v0.0.0→vol2-v0.1.0, with vol1 untouched).deploy_target=vol1,release_type=minor;should be
vol1-v0.5.1→vol1-v0.6.0(seeded from thelegacy
book-v0.5.1tag).Rollout sequence
When merged: the FIRST live publish should be a
deploy_target=vol1to establish
vol1-v0.6.0, thendeploy_target=vol2to establishvol2-v0.1.0. After both tags exist,deploy_target=allwill workfor joint releases.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.