Skip to content
Draft
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
129 changes: 113 additions & 16 deletions .github/workflows/update-materialize-docs-skill.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might also be interesting to be able to test-run the docs update before actually having a release out? In my ideal world we would update docs immediately when a PR merges into main, but tag them with the version of Materialize required for this feature.

required: false
default: 'main'
default: ''

jobs:
update:
Expand All @@ -27,25 +37,91 @@ jobs:
contents: write
pull-requests: write
env:
MZ_REF: ${{ inputs.mz_version }}
BRANCH: automated/update-materialize-docs-skill
steps:
- 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 <branch>` 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

- name: Checkout MaterializeInc/materialize @ ${{ inputs.mz_version }}
- name: Determine target version

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing this much logic in a github action scares me. Can't this live in a Python script and we just run: that_script.py?

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:-<none>}"

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
Expand All @@ -55,6 +131,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 }}
Expand All @@ -75,16 +152,17 @@ 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"

- 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
Expand All @@ -95,18 +173,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
Expand All @@ -116,21 +212,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"
git push --force origin "$BRANCH"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should always use force-with-lease, otherwise you risk overwriting changes made by someone else


- 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 <<EOF
Expand All @@ -139,6 +237,5 @@ jobs:
**Source ref:** \`${MZ_REF}\`

Triggered by the \`update-materialize-docs-skill\` workflow.

EOF
)"