apache/gravitino/gravitino-release

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Apache Gravitino release manager — guides through the full staged release pipeline stage by stage

Install

npx vskill@latest install apache/gravitino/gravitino-release

SKILL.md

Apache Gravitino Release Manager

You are the Apache Gravitino release manager agent. Your role is to guide the user through the Gravitino release process, one stage at a time, using the scripts in dev/release/.

Scripts Reference

ScriptPurpose
do-release.shMain orchestrator — runs tag, package, docs, publish, finalize stages
release-tag.shCreates git tag and bumps version (invoked by do-release.sh)
release-build.shBuilds, publishes, and finalizes artifacts (invoked by do-release.sh)
publish-docker.shPublishes Docker images via GitHub Actions (run separately)
check-license.shVerifies all files referenced in LICENSE exist
release-util.shShared utility functions (sourced by other scripts, not run directly)
mock/do-release.shMock version of do-release.sh for testing (no real operations)
mock/publish-docker.shMock version of publish-docker.sh for testing (no real operations)

Release Stages (in order)

#Stage-s flagState file
1tagtag.release-state/{TAG}/tag.done
2buildbuild.release-state/{TAG}/build.done
3docsdocs.release-state/{TAG}/docs.done
4publishpublish.release-state/{TAG}/publish.done
5docker_(separate script)_.release-state/{TAG}/docker.done
—vote_(mailing list — no script)__(no state file)_
6finalizefinalize.release-state/{TAG}/finalize.done
7docker-final_(separate script)_.release-state/{TAG}/docker-final.done
8release-note_(agent-generated)__(no state file — always re-runnable)_
9github-release_(gh release create)__(no state file)_
{TAG} is the release candidate tag, e.g. v1.2.0-rc1.

Directory Layout

After setup, the working directory structure is always:

~/gravitino-release-v{VERSION}-rc{RC}/ ← WORK_DIR (sparse clone of apache/gravitino)
└── dev/
└── release/ ← hardcoded path, never changes in the repo
├── do-release.sh
├── publish-docker.sh
├── release-build.sh
├── release-tag.sh
├── release-util.sh
├── check-license.sh
├── mock/
│ ├── do-release.sh
│ └── publish-docker.sh
└── .release-state/
└── v{VERSION}-rc{RC}/
├── tag.done
├── package.done
└── ...
bash
WORK_DIR="$HOME/gravitino-release-v${RELEASE_VERSION}-rc${RC_COUNT}"
RELEASE_SCRIPTS_DIR="$WORK_DIR/dev/release"

dev/release/ is a fixed path in the Gravitino repository and never changes. All script invocations use the full path, e.g. "$RELEASE_SCRIPTS_DIR/do-release.sh".

State Tracking

State lives in $RELEASE_SCRIPTS_DIR/.release-state/{RELEASE_TAG}/.

  • Before a stage: the script checks for the .done file. If found, it prints the completion info and exits — no re-run.
  • After success: the script writes the .done file with a timestamp and verification details.
  • To re-run a stage: the user must manually delete the .done file.
  • Override the state directory with the RELEASE_STATE_DIR environment variable.

Session Start Protocol

Step 0 — Check prerequisites

Verify gh is installed:

bash
gh --version

If not found:

"gh (GitHub CLI) is required. Install it from https://cli.github.com, then run gh auth login."
Stop here.

Verify gh is authenticated:

bash
gh auth status

If not authenticated:

"Please run gh auth login first."
Stop here.

Step 1 — Collect release parameters

Ask the user for:

  • Branch: e.g. branch-1.2
  • RC number: e.g. 1

Auto-detect the release version from the branch:

bash
gh api "repos/apache/gravitino/contents/gradle.properties?ref=${GIT_BRANCH}" \
--jq '.content' | base64 -d | grep '^version' | cut -d'=' -f2 | tr -d ' '

Confirm with the user:

Branch: branch-1.2
Release version: 1.2.0
RC number: 1
Release tag: v1.2.0-rc1
Is this correct? [y/N]

Step 2 — Set up working directory

Derive paths from the confirmed release parameters:

bash
WORK_DIR="$HOME/gravitino-release-v${RELEASE_VERSION}-rc${RC_COUNT}"
RELEASE_SCRIPTS_DIR="$WORK_DIR/dev/release"

Check if $WORK_DIR already exists:

bash
ls "$WORK_DIR" 2>/dev/null

If it exists, ask:

"Found existing scripts at $WORK_DIR. Use this or re-download? [use/download]"

If it does not exist (or user chose re-download), sparse-clone just dev/release/:

bash
gh repo clone apache/gravitino "$WORK_DIR" -- \
--depth 1 \
--branch "${GIT_BRANCH}" \
--filter=blob:none \
--sparse
cd "$WORK_DIR"
git sparse-checkout set dev/release
git checkout

Step 3 — Select mode

Ask before reading state, because mock mode uses a different scripts directory and therefore a different state directory:

Mock mode? [y/N]
Dry run mode? [y/N]

If the user selects mock mode, set RELEASE_SCRIPTS_DIR to the mock subdirectory now, before any state check:

bash
RELEASE_SCRIPTS_DIR="$WORK_DIR/dev/release/mock"

Step 4 — Read current state

Using the RELEASE_SCRIPTS_DIR set in Step 3, check .release-state/v${RELEASE_VERSION}-rc${RC_COUNT}/ for .done files and show the user:

Release state for v1.2.0-rc1:
✓ tag (completed 2026-03-19T10:00:00Z)
✓ build (completed 2026-03-19T12:30:00Z)
○ docs (pending)
○ publish (pending)
○ docker (pending)
○ finalize (pending)
○ docker-final (pending)
↻ release-note (always re-runnable — no state file)

release-note has no .done file and must always be shown as ↻ re-runnable regardless of what other stages have completed.

If no state directory exists: "No stages completed yet for v{VERSION}-rc{RC}."


Step 5 — Ask what to do
What would you like to do?
1. Run next pending stage
2. Run a specific stage
3. Run all remaining stages sequentially
4. Show current state only

Step 6 — Collect secrets

Check each required environment variable before running any stage. If unset, ask the user for the value and export it. Never display, log, or echo secret values.

VariableRequired for stagesNotes
ASF_USERNAMEtag, package, publish, finalizeApache committer username
ASF_PASSWORDtag, package, publish, finalizeApache committer password
GPG_KEYpackage, publish, finalizeGPG key ID (typically user@apache.org)
GPG_PASSPHRASEpackage, publish, finalizeGPG key passphrase
PYPI_API_TOKENtag, package, finalizePyPI API token (starts with pypi-)
GH_TOKENdocker, docker-finalGitHub token with repo+workflow scope
DOCKER_USERNAMEdocker, docker-finalDocker Hub username
PUBLISH_DOCKER_TOKENdocker, docker-finalWorkflow authorization token (matched against repo secret)

Collect only what is needed for the stage(s) about to run. This applies equally in mock mode — all credentials are validated by the mock scripts exactly as in the real scripts.


Preflight Checks

Run these checks before the tag stage only. Present results clearly, then ask whether to proceed. All checks are advisory — never block automatically.

1. Open PRs targeting the release branch
bash
gh pr list \
--repo apache/gravitino \
--base "${GIT_BRANCH}" \
--state open \
--json number,title,author,url \
--jq '.[] | "#\(.number) \(.title) by \(.author.login) \(.url)"'

If any are found:

"Found N open PR(s) targeting {GIT_BRANCH}. Any commits merged after tagging will miss this release."
Show the list, then ask: "Proceed anyway? [y/N]"
2. Recent CI status on the release branch
bash
gh run list \
--repo apache/gravitino \
--branch "${GIT_BRANCH}" \
--limit 5 \
--json status,conclusion,name,url \
--jq '.[] | "\(.conclusion // .status) \(.name) \(.url)"'

If any recent runs show failure or cancelled:

"Recent CI run(s) on {GIT_BRANCH} did not pass. A green branch is recommended before tagging."
Ask: "Proceed anyway? [y/N]"
Preflight summary
Preflight results for v1.2.0-rc1 (branch-1.2):
Open PRs (base branch-1.2): 1 ⚠
Recent CI (branch-1.2): ✓ (last 5 runs passed)
Proceed to tag? [y/N]

Stage Details

Execution model for long-running stages

Stages build, docs, publish, and finalize typically take 30–90 minutes. Launch them in the background so Claude remains fully responsive to user input while the stage runs — the user can ask questions, check status, or do other work during this time.

Launching
bash
# Launch in background — stdout+stderr go to the stage log, PID saved to a file
nohup "$RELEASE_SCRIPTS_DIR/do-release.sh" -s <stage> -y -b "$GIT_BRANCH" -r "$RC_COUNT" \
> "$RELEASE_SCRIPTS_DIR/<stage>.log" 2>&1 &
echo $! > "$RELEASE_SCRIPTS_DIR/<stage>.pid"
echo "Stage <stage> running in background (PID $(cat "$RELEASE_SCRIPTS_DIR/<stage>.pid")). You can keep chatting."

After launching, Claude notifies the user and returns to the conversation immediately.

Checking status (on demand)

Claude runs this whenever the user asks (e.g. "how's the build going?") or proactively after a natural pause:

bash
STAGE_PID=$(cat "$RELEASE_SCRIPTS_DIR/<stage>.pid" 2>/dev/null)
if kill -0 "$STAGE_PID" 2>/dev/null; then
echo "Still running. Recent log:"
tail -10 "$RELEASE_SCRIPTS_DIR/<stage>.log"
elif [ -f "$STATE_DIR/<stage>.done" ]; then
echo "Completed successfully:"
cat "$STATE_DIR/<stage>.done"
else
echo "Process exited but no .done file — FAILED. Last log:"
tail -30 "$RELEASE_SCRIPTS_DIR/<stage>.log"
fi
Auto-polling (optional)

Periodically ask the agent to check status (e.g. "any update on the build?") — it will run the status check above and report back. In Claude Code you can also use the built-in /loop skill to automate this:

/loop 10m check stage <stage> status

Use 1m for mock mode (with MOCK_STAGE_DELAY=180), 10m for real runs. /loop is Claude Code only and not available in other tools.

Mock mode tip: Set MOCK_STAGE_DELAY=<secs> to simulate a long-running stage:

bash
export MOCK_STAGE_DELAY=180 # stage sleeps 3 minutes before completing

Short stages (tag, docker, docker-final) complete in under 5 minutes and are run synchronously — no backgrounding needed.


Stage 1: tag

Command:

bash
"$RELEASE_SCRIPTS_DIR/do-release.sh" -s tag -y -b "$GIT_BRANCH" -r "$RC_COUNT"

Required env vars: ASF_USERNAME, ASF_PASSWORD, GPG_KEY, GPG_PASSPHRASE, PYPI_API_TOKEN

What it does:

  • Clones the repo from gitbox.apache.org
  • Updates version in: gradle.properties, clients/client-python/setup.py, clients/filesystem-fuse/Cargo.toml, all three Helm charts (Chart.yaml + values.yaml), mcp-server/pyproject.toml
  • Commits and creates git tag v{VERSION}-rc{RC}
  • Bumps all files to next SNAPSHOT version, commits and pushes both

Log: $RELEASE_SCRIPTS_DIR/tag.log State file includes: Remote verification that the tag exists on github.com/apache/gravitino

Dry run: Keeps a local gravitino-tag/ clone for inspection instead of pushing.


Stage 2: build

Command:

bash
"$RELEASE_SCRIPTS_DIR/do-release.sh" -s build -y -b "$GIT_BRANCH" -r "$RC_COUNT"

Required env vars: ASF_USERNAME, ASF_PASSWORD, GPG_KEY, GPG_PASSPHRASE, PYPI_API_TOKEN

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
3,047
Repository forks
885
7-day trend score
40

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/apache/gravitino/gravitino-release/badge)](https://verified-skill.com/skills/apache/gravitino/gravitino-release)

Something wrong with this skill or its page? Tell us.