From a646121f3d32c79423c7229fb772d78954aa3dd2 Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Tue, 28 Apr 2026 16:25:01 -0400 Subject: [PATCH 1/3] Auto-detect target Materialize version from releases/_index.md When `mz_version` input is empty, the workflow now reads level-2 version headings from doc/user/content/releases/_index.md on materialize@main, takes the highest, and compares against the version recorded in the heading of skills/materialize-docs/README.md. It only regenerates when the upstream release is strictly newer, and updates the README heading to the new version after a successful auto-bump. The PR is created non-draft, and explicit `mz_version` invocations still bypass version-checking and leave the README heading alone. Co-Authored-By: Claude Sonnet 4.6 --- .../update-materialize-docs-skill.yml | 112 ++++++++++++++++-- 1 file changed, 102 insertions(+), 10 deletions(-) diff --git a/.github/workflows/update-materialize-docs-skill.yml b/.github/workflows/update-materialize-docs-skill.yml index c1414f3..2c1910c 100644 --- a/.github/workflows/update-materialize-docs-skill.yml +++ b/.github/workflows/update-materialize-docs-skill.yml @@ -3,6 +3,16 @@ # Generator: https://github.com/MaterializeInc/materialize/blob/main/bin/gen-claude-skill # Target: https://github.com/MaterializeInc/agent-skills/tree/main/skills/materialize-docs # +# When triggered without an `mz_version` input, the workflow auto-detects the +# latest Materialize release by reading level-2 version headings from +# `doc/user/content/releases/_index.md` on `main`. It only regenerates if the +# latest release is strictly greater than the version recorded in the heading +# of `skills/materialize-docs/README.md` (`# materialize-docs vX.Y.Z`). After +# a successful auto-bump, the README heading is updated to the new version. +# +# When triggered with an explicit `mz_version`, the workflow always regenerates +# at that ref and does not modify the README heading. +# # The generator uses `hugo --cleanDestinationDir`, so it wipes the output # directory on each run. Hand-maintained files (the skill's top-level README # and references/README) are stashed before generation and restored after. @@ -15,9 +25,9 @@ on: workflow_dispatch: inputs: mz_version: - description: 'Materialize ref (tag, branch, or commit SHA). Defaults to main.' + description: 'Materialize ref (tag, branch, or commit SHA). Leave empty to auto-detect the latest release.' required: false - default: 'main' + default: '' jobs: update: @@ -27,7 +37,6 @@ jobs: contents: write pull-requests: write env: - MZ_REF: ${{ inputs.mz_version }} BRANCH: automated/update-materialize-docs-skill steps: - name: Checkout agent-skills @@ -37,15 +46,77 @@ jobs: fetch-depth: 0 persist-credentials: false - - name: Checkout MaterializeInc/materialize @ ${{ inputs.mz_version }} + - name: Determine target version + id: target + working-directory: agent-skills + env: + INPUT_MZ_VERSION: ${{ inputs.mz_version }} + run: | + set -euo pipefail + + if [ -n "$INPUT_MZ_VERSION" ]; then + echo "User-specified ref: $INPUT_MZ_VERSION" + { + echo "should_run=true" + echo "mz_ref=$INPUT_MZ_VERSION" + echo "update_readme=false" + echo "new_version=" + } >> "$GITHUB_OUTPUT" + exit 0 + fi + + RAW_URL="https://raw.githubusercontent.com/MaterializeInc/materialize/main/doc/user/content/releases/_index.md" + LATEST=$(curl -fsSL "$RAW_URL" \ + | grep -E '^##[[:space:]]+v[0-9]+\.[0-9]+\.[0-9]+' \ + | sed -E 's/^##[[:space:]]+(v[0-9]+\.[0-9]+\.[0-9]+).*/\1/' \ + | sort -V \ + | tail -1) + if [ -z "$LATEST" ]; then + echo "Failed to find any 'vX.Y.Z' headings in _index.md" >&2 + exit 1 + fi + echo "Latest release in _index.md: $LATEST" + + CURRENT=$(sed -nE '1s/^# materialize-docs[[:space:]]+(v[0-9]+\.[0-9]+\.[0-9]+).*/\1/p' skills/materialize-docs/README.md || true) + echo "Current version in README: ${CURRENT:-}" + + if [ -z "$CURRENT" ]; then + echo "No current version recorded; bootstrapping to $LATEST" + SHOULD_RUN=true + else + HIGHEST=$(printf '%s\n%s\n' "$CURRENT" "$LATEST" | sort -V | tail -1) + if [ "$HIGHEST" = "$LATEST" ] && [ "$LATEST" != "$CURRENT" ]; then + echo "New release detected: $CURRENT -> $LATEST" + SHOULD_RUN=true + else + echo "Already up to date at $CURRENT" + SHOULD_RUN=false + fi + fi + + if [ "$SHOULD_RUN" != "true" ]; then + echo "should_run=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + { + echo "should_run=true" + echo "mz_ref=$LATEST" + echo "update_readme=true" + echo "new_version=$LATEST" + } >> "$GITHUB_OUTPUT" + + - name: Checkout MaterializeInc/materialize + if: steps.target.outputs.should_run == 'true' uses: actions/checkout@v4 with: repository: MaterializeInc/materialize - ref: ${{ inputs.mz_version }} + ref: ${{ steps.target.outputs.mz_ref }} path: materialize fetch-depth: 1 - name: Set up Hugo (extended) + if: steps.target.outputs.should_run == 'true' uses: peaceiris/actions-hugo@v3 with: # Pinned to match the version used in MaterializeInc/materialize CI @@ -55,6 +126,7 @@ jobs: - name: Set up branch id: branch + if: steps.target.outputs.should_run == 'true' working-directory: agent-skills env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -85,6 +157,7 @@ jobs: echo "existing_pr=$EXISTING_PR" >> "$GITHUB_OUTPUT" - name: Stash hand-maintained files + if: steps.target.outputs.should_run == 'true' working-directory: agent-skills run: | # The generator runs `hugo --cleanDestinationDir`, which wipes the @@ -95,18 +168,36 @@ jobs: cp skills/materialize-docs/references/README.md ../preserved/references/README.md - name: Generate skill + if: steps.target.outputs.should_run == 'true' working-directory: materialize run: bin/gen-claude-skill ../agent-skills/skills/materialize-docs - name: Restore hand-maintained files + if: steps.target.outputs.should_run == 'true' working-directory: agent-skills run: | mkdir -p skills/materialize-docs/references cp ../preserved/README.md skills/materialize-docs/README.md cp ../preserved/references/README.md skills/materialize-docs/references/README.md + - name: Update README version heading + if: steps.target.outputs.should_run == 'true' && steps.target.outputs.update_readme == 'true' + working-directory: agent-skills + env: + NEW_VERSION: ${{ steps.target.outputs.new_version }} + run: | + set -euo pipefail + if ! head -1 skills/materialize-docs/README.md | grep -q '^# materialize-docs'; then + echo "Expected line 1 of README to start with '# materialize-docs'; aborting." >&2 + head -1 skills/materialize-docs/README.md >&2 + exit 1 + fi + sed -i "1s|.*|# materialize-docs ${NEW_VERSION}|" skills/materialize-docs/README.md + echo "Updated README heading to: $(head -1 skills/materialize-docs/README.md)" + - name: Check for changes id: changes + if: steps.target.outputs.should_run == 'true' working-directory: agent-skills run: | if [ -z "$(git status --porcelain)" ]; then @@ -116,21 +207,23 @@ jobs: fi - name: Commit and push - if: steps.changes.outputs.has_changes == 'true' + if: steps.target.outputs.should_run == 'true' && steps.changes.outputs.has_changes == 'true' working-directory: agent-skills + env: + MZ_REF: ${{ steps.target.outputs.mz_ref }} run: | git add skills/materialize-docs git commit -m "Update materialize-docs skill from materialize@${MZ_REF}" git push origin "$BRANCH" - - name: Create draft PR - if: steps.changes.outputs.has_changes == 'true' && steps.branch.outputs.existing_pr == '' + - name: Create PR + if: steps.target.outputs.should_run == 'true' && steps.changes.outputs.has_changes == 'true' && steps.branch.outputs.existing_pr == '' working-directory: agent-skills env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MZ_REF: ${{ steps.target.outputs.mz_ref }} run: | gh pr create \ - --draft \ --head "$BRANCH" \ --title "Update materialize-docs skill from materialize@${MZ_REF}" \ --body "$(cat < Date: Tue, 28 Apr 2026 19:47:08 -0400 Subject: [PATCH 2/3] Pin agent-skills checkout to the default branch When the workflow is dispatched on a feature branch via `gh workflow run --ref `, actions/checkout would otherwise default to that branch's tree. The auto-bump PR then inherits the feature-branch changes (e.g. the workflow file itself). Pin the checkout to the default branch so test runs and production runs both produce auto-bump PRs that contain only generated content. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/update-materialize-docs-skill.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/update-materialize-docs-skill.yml b/.github/workflows/update-materialize-docs-skill.yml index 2c1910c..e138540 100644 --- a/.github/workflows/update-materialize-docs-skill.yml +++ b/.github/workflows/update-materialize-docs-skill.yml @@ -42,6 +42,11 @@ jobs: - name: Checkout agent-skills uses: actions/checkout@v4 with: + # Always check out the default branch, not the ref the workflow was + # dispatched from. Otherwise testing the workflow on a feature branch + # via `gh workflow run --ref ` would carry that branch's + # changes into the auto-bump PR. + ref: ${{ github.event.repository.default_branch }} path: agent-skills fetch-depth: 0 persist-credentials: false From 9d5bef89e866f15e9bdd0ae494de9af2408815ab Mon Sep 17 00:00:00 2001 From: Jon Currey Date: Mon, 4 May 2026 17:49:04 -0400 Subject: [PATCH 3/3] Fix branch deletion failure after PR merge Branch protection forbids deleting `automated/update-materialize-docs-skill`, so `git push origin --delete` fails on the next run after a PR merges. Instead, reset the branch locally from origin/main and force-push, which overwrites the stale remote ref without needing to delete it. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/update-materialize-docs-skill.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/update-materialize-docs-skill.yml b/.github/workflows/update-materialize-docs-skill.yml index e138540..f061856 100644 --- a/.github/workflows/update-materialize-docs-skill.yml +++ b/.github/workflows/update-materialize-docs-skill.yml @@ -152,11 +152,11 @@ jobs: git reset --hard origin/main fi else - if git ls-remote --exit-code origin "refs/heads/$BRANCH" >/dev/null 2>&1; then - echo "Deleting stale remote branch $BRANCH (no open PR)" - git push origin --delete "$BRANCH" - fi - git checkout -b "$BRANCH" + # No open PR for this branch. Reset locally from main; the push step + # uses --force, which overwrites any stale remote branch left over + # from a previously-merged PR (branch protection forbids deleting it). + echo "No open PR; starting branch fresh from origin/main" + git checkout -B "$BRANCH" origin/main fi echo "existing_pr=$EXISTING_PR" >> "$GITHUB_OUTPUT" @@ -219,7 +219,7 @@ jobs: run: | git add skills/materialize-docs git commit -m "Update materialize-docs skill from materialize@${MZ_REF}" - git push origin "$BRANCH" + git push --force origin "$BRANCH" - name: Create PR if: steps.target.outputs.should_run == 'true' && steps.changes.outputs.has_changes == 'true' && steps.branch.outputs.existing_pr == ''