Skip to content

Auto-release updates #143

Auto-release updates

Auto-release updates #143

Workflow file for this run

name: Auto-release updates
on:
schedule:
- cron: "0 */6 * * *" # every 6 hours
workflow_dispatch:
permissions:
contents: write
pull-requests: write
actions: write
jobs:
refresh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
# Use the existing chore/changelog-refresh branch (if any) as the
# comparison baseline instead of main. This prevents re-triggering the
# Mintlify agent every 6 hours for releases that were already processed
# but whose PR has not been merged yet. When the PR is merged or closed
# (with delete-branch: true below), the branch disappears and the next
# release is detected normally.
- name: Use existing changelog refresh branch as baseline
run: |
if git ls-remote --exit-code --heads origin chore/changelog-refresh >/dev/null 2>&1; then
git fetch origin chore/changelog-refresh
git checkout origin/chore/changelog-refresh -- docs/changelog/ || true
echo "Baseline restored from chore/changelog-refresh branch."
else
echo "No chore/changelog-refresh branch; using main as baseline."
fi
- name: Regenerate docs/changelog from GitHub releases
run: node scripts/generate-changelog.js
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CHANGELOG_CACHE_TTL_SECONDS: "0"
CHANGELOG_CHANGES_FILE: /tmp/changelog-changes.json
- name: Read changelog changes
id: changes
run: |
if [ ! -f /tmp/changelog-changes.json ] || [ "$(jq length /tmp/changelog-changes.json)" -eq 0 ]; then
echo "No changelog changes detected."
echo "pages=" >> "$GITHUB_OUTPUT"
echo "has_sdk_updates=false" >> "$GITHUB_OUTPUT"
exit 0
fi
PAGES=$(jq -r '[.[].page] | join(" ")' /tmp/changelog-changes.json)
echo "pages=${PAGES}" >> "$GITHUB_OUTPUT"
# Read ALL latest versions from the cache file (updated by generate-changelog.js).
# This ensures the pre-release workflow always gets every SDK's current version,
# not just the ones whose changelog page happened to change in this run.
CACHE=scripts/.changelog-cache.json
echo "restate_version=$(jq -r '.repos.restate.releases[0].tag_name // empty' "$CACHE" | sed 's/^v//')" >> "$GITHUB_OUTPUT"
echo "ts_version=$(jq -r '.repos["sdk-typescript"].releases[0].tag_name // empty' "$CACHE" | sed 's/^v//')" >> "$GITHUB_OUTPUT"
echo "python_version=$(jq -r '.repos["sdk-python"].releases[0].tag_name // empty' "$CACHE" | sed 's/^v//')" >> "$GITHUB_OUTPUT"
echo "java_version=$(jq -r '.repos["sdk-java"].releases[0].tag_name // empty' "$CACHE" | sed 's/^v//')" >> "$GITHUB_OUTPUT"
echo "go_version=$(jq -r '.repos["sdk-go"].releases[0].tag_name // empty' "$CACHE" | sed 's/^v//')" >> "$GITHUB_OUTPUT"
echo "rust_version=$(jq -r '.repos["sdk-rust"].releases[0].tag_name // empty' "$CACHE" | sed 's/^v//')" >> "$GITHUB_OUTPUT"
# Check if any non-operator SDK page changed
HAS=$(jq -r '[.[] | select(.page != "operator") | .latestVersion // empty | select(. != "")] | if length > 0 then "true" else "false" end' /tmp/changelog-changes.json)
echo "has_sdk_updates=${HAS}" >> "$GITHUB_OUTPUT"
echo "Changes detected:"
jq -r '.[] | " \(.label) \(.latestVersion) — \(.latestReleaseUrl)"' /tmp/changelog-changes.json
- name: Trigger pre-release workflow
if: steps.changes.outputs.has_sdk_updates == 'true'
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
ARGS=""
RESTATE_V="${{ steps.changes.outputs.restate_version }}"
TS_V="${{ steps.changes.outputs.ts_version }}"
PYTHON_V="${{ steps.changes.outputs.python_version }}"
JAVA_V="${{ steps.changes.outputs.java_version }}"
GO_V="${{ steps.changes.outputs.go_version }}"
RUST_V="${{ steps.changes.outputs.rust_version }}"
[ -n "$RESTATE_V" ] && ARGS="$ARGS -f restateVersion=$RESTATE_V"
[ -n "$TS_V" ] && ARGS="$ARGS -f sdkTypescriptVersion=$TS_V"
[ -n "$PYTHON_V" ] && ARGS="$ARGS -f sdkPythonVersion=$PYTHON_V"
[ -n "$JAVA_V" ] && ARGS="$ARGS -f sdkJavaVersion=$JAVA_V"
[ -n "$GO_V" ] && ARGS="$ARGS -f sdkGoVersion=$GO_V"
[ -n "$RUST_V" ] && ARGS="$ARGS -f sdkRustVersion=$RUST_V"
echo "Dispatching pre-release workflow with:${ARGS}"
gh workflow run pre-release.yml $ARGS
sleep 5
RUN_URL=$(gh run list --workflow pre-release.yml --limit 1 --json url --jq '.[0].url')
echo "Pre-release workflow run: ${RUN_URL}"
- name: Open or update changelog refresh PR
uses: peter-evans/create-pull-request@v6
with:
commit-message: "chore: refresh changelog from GitHub releases"
title: "chore: refresh changelog"
body: |
Automated changelog refresh from GitHub releases across the
restatedev org. Review the rendered `docs/changelog.mdx` and merge
when the output looks right.
branch: chore/changelog-refresh
delete-branch: true
add-paths: docs/changelog
reviewers: gvdongen
labels: |
automated
changelog
- name: Trigger Mintlify agent per SDK
if: steps.changes.outputs.pages != ''
continue-on-error: true
timeout-minutes: 30
env:
MINTLIFY_API_KEY: ${{ secrets.MINTLIFY_API_KEY }}
MINTLIFY_PROJECT_ID: ${{ secrets.MINTLIFY_PROJECT_ID }}
run: |
# Phase 1: Create agent jobs for each changed SDK
jq -c '.[]' /tmp/changelog-changes.json | while IFS= read -r entry; do
LABEL=$(echo "$entry" | jq -r '.label')
# Count new releases for this page
RELEASE_COUNT=$(echo "$entry" | jq '.newReleases | length')
if [ "$RELEASE_COUNT" -eq 0 ] 2>/dev/null; then
echo "${LABEL}: No new releases detected, skipping Mintlify agent."
continue
fi
# Build a list of all new releases: "- ProductTag vX.Y.Z: <url>"
RELEASE_LIST=$(echo "$entry" | jq -r '.newReleases[] | "- \(.productTag) \(.tagName): \(.releaseUrl)"')
PROMPT="The following ${LABEL} releases were published:
${RELEASE_LIST}
Review ALL of the above release notes and update the documentation accordingly.
For each user-facing change across these releases:
1. Dig into the linked PRs from the release notes to fully understand the change, its motivation, and usage.
2. Draft or update documentation pages in the /docs directory that explain what the feature does, when to use it, and how to configure it.
3. Update the /restate-plugin/src directory to reflect the latest changes in the SDK. Only do this for features that are important enough to be loaded as part of Restate's Coding Agent skills.
3. Include code examples where relevant. All code snippets MUST be placed in the /snippets directory organized by language (ts, java, kotlin, python, go, rust) and referenced from MDX docs using the CODE_LOAD syntax. Use <start_tag>/<end_tag> markers in snippet files for section extraction. See CLAUDE.md for full CODE_LOAD details.
4. Create a PR with the updated documentation.
Success criteria: After reading any new or updated documentation, users understand what the feature is, whether it applies to their use case, and how to use it.
Important:
- Only document changes that affect end users. Skip internal refactors or dependency updates.
- Match the style and structure of existing docs pages.
- If no user-facing changes were introduced, do nothing.
- Do not include private repository file paths, directory structures, code snippets, or any other internal implementation details in PR titles, descriptions, or commit messages.
- Write a quick summary of the ${LABEL} features that shipped in the PR description."
HTTP_STATUS=$(jq -n --arg prompt "$PROMPT" '{prompt: $prompt}' | \
curl -sS -o /tmp/mintlify-response.json -w "%{http_code}" \
-X POST "https://api.mintlify.com/v2/agent/${MINTLIFY_PROJECT_ID}/job" \
-H "Authorization: Bearer ${MINTLIFY_API_KEY}" \
-H "Content-Type: application/json" \
-d @-)
JOB_ID=$(jq -r '.id' /tmp/mintlify-response.json)
if [ "$HTTP_STATUS" -ge 200 ] && [ "$HTTP_STATUS" -lt 300 ] && \
[ -n "$JOB_ID" ] && [ "$JOB_ID" != "null" ]; then
echo "${LABEL}: Created agent job ${JOB_ID} for ${RELEASE_COUNT} release(s)"
echo "${JOB_ID}|${LABEL}" >> /tmp/mintlify-jobs.txt
else
echo "::warning::Failed to create agent job for ${LABEL} (HTTP ${HTTP_STATUS})"
fi
done
# Phase 2: Poll all jobs until each completes or fails
[ ! -f /tmp/mintlify-jobs.txt ] && exit 0
echo "Polling $(wc -l < /tmp/mintlify-jobs.txt) agent job(s)..."
while [ -s /tmp/mintlify-jobs.txt ]; do
sleep 30
> /tmp/mintlify-pending.txt
while IFS='|' read -r JOB_ID LABEL; do
POLL_RESPONSE=$(curl -sS \
"https://api.mintlify.com/v2/agent/${MINTLIFY_PROJECT_ID}/job/${JOB_ID}" \
-H "Authorization: Bearer ${MINTLIFY_API_KEY}")
JOB_STATUS=$(echo "$POLL_RESPONSE" | jq -r '.status')
case "$JOB_STATUS" in
completed)
PR_LINK=$(echo "$POLL_RESPONSE" | jq -r '.prLink // empty')
if [ -n "$PR_LINK" ]; then
echo "${LABEL}: PR created -- ${PR_LINK}"
else
echo "${LABEL}: Completed (no changes needed)"
fi ;;
failed|archived)
echo "::warning::${LABEL} agent job ${JOB_STATUS}" ;;
active)
echo "${LABEL}: Still running..."
echo "${JOB_ID}|${LABEL}" >> /tmp/mintlify-pending.txt ;;
*)
echo "::warning::${LABEL} unexpected status: ${JOB_STATUS}" ;;
esac
done < /tmp/mintlify-jobs.txt
mv /tmp/mintlify-pending.txt /tmp/mintlify-jobs.txt
done