diff --git a/.dagger/src/blumeops_ci/main.py b/.dagger/src/blumeops_ci/main.py index 8f2373f..5cd70e4 100644 --- a/.dagger/src/blumeops_ci/main.py +++ b/.dagger/src/blumeops_ci/main.py @@ -23,36 +23,15 @@ class BlumeopsCi: ref = f"{registry}/blumeops/{container_name}:{version}" return await ctr.publish(ref) - @function - async def build_changelog( - self, src: dagger.Directory, version: str - ) -> dagger.Directory: - """Run towncrier to build changelog, return modified source tree.""" - return await ( - dag.container() - .from_("python:3.12-slim") - .with_env_variable("TZ", "America/Los_Angeles") - # git is required because towncrier stages CHANGELOG.md via git add - .with_exec(["apt-get", "update", "-qq"]) - .with_exec(["apt-get", "install", "-y", "-qq", "git"]) - .with_exec(["pip", "install", "towncrier"]) - .with_directory("/workspace", src) - .with_workdir("/workspace") - .with_exec(["git", "init"]) - .with_exec(["towncrier", "build", "--version", version, "--yes"]) - .directory("/workspace") - ) - @function async def build_docs(self, src: dagger.Directory, version: str) -> dagger.File: - """Build changelog then Quartz site. Returns docs tarball.""" - updated_src = await self.build_changelog(src, version) + """Build Quartz docs site. Returns docs tarball.""" return await ( dag.container() .from_("node:22-slim") .with_exec(["apt-get", "update", "-qq"]) .with_exec(["apt-get", "install", "-y", "-qq", "git"]) - .with_directory("/workspace", updated_src) + .with_directory("/workspace", src) .with_workdir("/workspace") .with_exec( [ diff --git a/.forgejo/workflows/build-blumeops.yaml b/.forgejo/workflows/build-blumeops.yaml index dca745a..e771033 100644 --- a/.forgejo/workflows/build-blumeops.yaml +++ b/.forgejo/workflows/build-blumeops.yaml @@ -108,30 +108,14 @@ jobs: with: fetch-depth: 0 - - name: Build docs - run: | - VERSION="${{ steps.version.outputs.version }}" - TARBALL="docs-${VERSION}.tar.gz" - echo "Building docs via Dagger..." - # build-docs calls build_changelog internally (towncrier runs inside - # the Dagger container). The host working tree is not modified — only - # the tarball is exported. Towncrier runs a second time on the runner - # in the next step so that CHANGELOG.md and fragment deletion are - # captured in the git commit. - dagger call build-docs --src=. --version="$VERSION" \ - export --path="./$TARBALL" - echo "Build complete!" - ls -lh "$TARBALL" - - name: Build changelog id: changelog run: | VERSION="${{ steps.version.outputs.version }}" - # Run towncrier on the runner (not in Dagger) so that CHANGELOG.md - # updates and fragment deletions appear in the working tree for the - # git commit step. This is intentionally a second towncrier run — - # the first happened inside the Dagger build-docs container above. + # Run towncrier on the runner so that CHANGELOG.md updates and + # fragment deletions appear in the working tree for both the Quartz + # build (next step) and the git commit step. # Check if there are any changelog fragments FRAGMENTS=$(find docs/changelog.d -name "*.md" -not -name ".gitkeep" 2>/dev/null | wc -l) @@ -157,6 +141,19 @@ jobs: echo "" > /tmp/release_notes.md fi + - name: Build docs + run: | + VERSION="${{ steps.version.outputs.version }}" + TARBALL="docs-${VERSION}.tar.gz" + echo "Building docs via Dagger..." + # Towncrier already ran on the runner above, so the working tree + # has an up-to-date CHANGELOG.md. build-docs now only runs the + # Quartz static site build (no towncrier). + dagger call build-docs --src=. --version="$VERSION" \ + export --path="./$TARBALL" + echo "Build complete!" + ls -lh "$TARBALL" + - name: Create release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/docs/changelog.d/eliminate-double-towncrier.infra.md b/docs/changelog.d/eliminate-double-towncrier.infra.md new file mode 100644 index 0000000..3c6524d --- /dev/null +++ b/docs/changelog.d/eliminate-double-towncrier.infra.md @@ -0,0 +1 @@ +Eliminate double towncrier run in release workflow — changelog is now built once on the runner, then the pre-processed source tree is passed to a new `build_quartz` Dagger function for the Quartz site build only. diff --git a/docs/how-to/update-documentation.md b/docs/how-to/update-documentation.md index e9991e6..4df624c 100644 --- a/docs/how-to/update-documentation.md +++ b/docs/how-to/update-documentation.md @@ -26,7 +26,7 @@ Direct link: https://forge.ops.eblu.me/eblume/blumeops/actions?workflow=build-bl The `build-blumeops` workflow (`.forgejo/workflows/build-blumeops.yaml`): 1. **Resolves version** — Uses input or auto-increments from latest release -2. **Builds changelog** — Calls `dagger call build-changelog` (towncrier in a container) +2. **Builds changelog** — Runs towncrier on the runner to update `CHANGELOG.md` 3. **Builds docs** — Calls `dagger call build-docs` (Quartz build in a container) 4. **Creates release** — Uploads `docs-.tar.gz` to Forgejo releases 5. **Updates deployment** — Edits `argocd/manifests/docs/deployment.yaml` with new URL diff --git a/docs/reference/tools/dagger.md b/docs/reference/tools/dagger.md index c78a706..a793d9b 100644 --- a/docs/reference/tools/dagger.md +++ b/docs/reference/tools/dagger.md @@ -27,8 +27,7 @@ Build engine for BlumeOps CI/CD pipelines. Replaces shell-based build scripts wi |----------|-----------|-------------| | `build` | `(src, container_name) → Container` | Build a container from `containers//Dockerfile` | | `publish` | `(src, container_name, version, registry?) → str` | Build and push to registry (default: `registry.ops.eblu.me`) | -| `build_changelog` | `(src, version) → Directory` | Run towncrier to collect changelog fragments | -| `build_docs` | `(src, version) → File` | Build changelog then Quartz site, return docs tarball | +| `build_docs` | `(src, version) → File` | Build Quartz docs site, return docs tarball | ## CLI Examples