本文へ移動
cccskills
無料GitHub で公開日本語紹介

gravitino-release

Apache Gravitinoのリリース作業を段階ごとに進めるためのスキルです。タグ作成から成果物のビルド、公開、投票後の確定、リリースノート作成までの手順と状態を管理します。

原文原文の説明を見る

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

apache/gravitinoスター 3,337(GitHub 3,337 + cccskills 0)
連携ツールGitHubDocker

実行スコア 未検証

インストール方法を見る

こんなときに便利

  • Gravitinoのリリース候補を準備したいとき
  • 完了済みのリリース工程を確認したいとき
  • 特定ステージの実行や事前確認をしたいとき
  • 課題一覧からリリースノートを作りたいとき

日本語での紹介

できること

Apache Gravitinoのリリースを、タグ作成、成果物のビルド、ドキュメント生成、Maven/Nexusへの公開、Dockerイメージ作成、投票、最終確定などの段階に分けて進める手順を案内します。各段階で使うスクリプトや必要な認証情報、完了状態の記録を確認し、次に実行する作業を選べます。モック用スクリプトで実処理を行わずに流れを試す方法や、リリース対象の課題一覧からノートの草案を作る方法も含まれています。

こんなときに便利

Gravitinoのリリース担当者が、作業の順序や準備状況を確認しながら進めたいときに向いています。途中まで完了したリリースの状態確認や、個別ステージの実行、投票後の最終化にも使えます。

使い方の例

  • 「branch-1.2のリリース準備を始めたい」
  • 「現在のリリース状態を確認して、次のステージを教えて」
  • 「リリース対象の課題からノートの草案を作って」

注意点

GitHub CLIのghと認証が必要です。ステージに応じてApache、GPG、PyPI、GitHub、Dockerの認証情報が必要になります。実際の公開や最終確定を伴う操作があり、finalizeはタグや配布成果物を確定する取り消せない処理として明示的な確認を求めます。資料は途中までのため、後半の詳細は含めていません。

この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。

含まれるファイル(2)

  • SKILL.md26.1 KB
  • README.md3.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -->

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
                └── ...
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:

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:

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:

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:

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

Check if $WORK_DIR already exists:

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/:

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:

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

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

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

# 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:

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:

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:

"$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:

"$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

What it does:

  • Clones from the release tag
  • Builds source tarball (gravitino-{VERSION}-src.tar.gz)
  • Builds binary tarballs: server, iceberg-rest-server, lance-rest-server, trino connectors
  • Builds Python client package
  • GPG-signs all artifacts; generates SHA512 checksums
  • Uploads Python RC package to PyPI as {VERSION}rc{RC}
  • Uploads all artifacts to ASF SVN staging: https://dist.apache.org/repos/dist/dev/gravitino/v{VERSION}-rc{RC}/

Log: $RELEASE_SCRIPTS_DIR/build.log


Stage 3: docs

Command:

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

Required env vars: (none — docs build is fully local)

What it does:

  • Builds Javadoc from clients/client-java → gravitino-{VERSION}-javadoc/
  • Builds Python Sphinx docs from clients/client-python → gravitino-{VERSION}-pydoc/
  • Output is local only; nothing is published in this stage

Log: $RELEASE_SCRIPTS_DIR/docs.log


Stage 4: publish (Maven/Nexus)

Command:

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

Required env vars: ASF_USERNAME, ASF_PASSWORD, GPG_KEY, GPG_PASSPHRASE

What it does:

  • Creates an Apache Nexus staging repository
  • Builds Maven artifacts for Scala 2.12 and Scala 2.13
  • Signs each artifact and uploads to Nexus
  • Closes the staging repository (making it available for the vote)

Log: $RELEASE_SCRIPTS_DIR/publish.log


Stage 5: docker

Command:

"$RELEASE_SCRIPTS_DIR/publish-docker.sh" "v${RELEASE_VERSION}-rc${RC_COUNT}" \
  --docker-version "${RELEASE_VERSION}-rc${RC_COUNT}" \
  --trino-version "${TRINO_VERSION:-478}"

Required env vars: GH_TOKEN (or active gh auth login), DOCKER_USERNAME, PUBLISH_DOCKER_TOKEN

What it does: Triggers GitHub Actions docker-image.yml workflow for each image:

  • apache/gravitino:{VERSION}-rc{RC}
  • apache/gravitino-iceberg-rest:{VERSION}-rc{RC}
  • apache/gravitino-lance-rest:{VERSION}-rc{RC}
  • apache/gravitino-mcp-server:{VERSION}-rc{RC}
  • apache/gravitino-playground:trino-{TRINO_VER}-gravitino-{VERSION}-rc{RC}

Default Trino version: 478 — ask the user if they want a different version before running.

Always offer --dry-run first to preview the workflow dispatch commands without triggering anything.

Monitor progress: https://github.com/apache/gravitino/actions/workflows/docker-image.yml


Vote (between docker and finalize)

No script covers this stage.

Send [VOTE] to dev@gravitino.apache.org once the RC artifacts, PyPI staging, Maven staging and Docker images are all verified. The mail must carry the git tag and commit, the dist/dev URL, the staging repository, the KEYS URL, and how to verify signatures.

The rules (ASF release policy):

  • Open at least 72 hours. A shorter period must be justified in the mail.
  • Needs at least 3 binding +1, and more binding +1 than binding -1. Binding means PMC member; non-binding votes are encouraged and tallied separately.
  • Releases may not be vetoed — a single -1 does not by itself block the vote. In practice, if anyone reports a real problem the release manager cancels the vote rather than carrying it.

On a -1: answer the technical point on the thread. If it holds, cancel, fix, and cut the next RC — the RC number increments, the version does not.

When it passes, send [RESULT][VOTE] as a new thread, not a reply. List every voter, marked binding or non-binding, and give the tally.

Then note which RC passed. finalize needs -r set to that RC, and the RC number is not auto-detected correctly: release-util.sh derives it as the count of existing v<version>-rc* tags plus one, which after rc1, rc2 and rc3 gives 4. A release that needed more than one RC will finalize against a dist/dev path that never existed unless -r is passed explicitly.


Stage 6: finalize

⚠️ Irreversible. Always get explicit user confirmation before running.

Confirmation prompt:

finalize will permanently:
  - Create git tag v{VERSION} (no rc suffix)
  - Upload final Python package to PyPI (without rc suffix)
  - Move SVN artifacts: dev/gravitino/v{VERSION}-rc{RC} → release/gravitino/{VERSION}
  - Update the public KEYS file

This cannot be undone. Type 'yes' to proceed:

Command:

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

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

Log: $RELEASE_SCRIPTS_DIR/finalize.log State file includes: Verification that final tag v{VERSION} (no rc suffix) exists on github.com


Stage 7: docker-final

Command:

RELEASE_STATE_DIR="$RELEASE_SCRIPTS_DIR/.release-state/$RELEASE_TAG" \
"$RELEASE_SCRIPTS_DIR/publish-docker.sh" "v${RELEASE_VERSION}" \
  --docker-version "${RELEASE_VERSION}" \
  --trino-version "${TRINO_VERSION:-478}" \
  --state-key "docker-final"

Required env vars: GH_TOKEN (or active gh auth login), DOCKER_USERNAME, PUBLISH_DOCKER_TOKEN

Optional env vars: TRINO_VERSION — Trino version for the playground image (default: 478). Ask the user before running if they want a different version.

What it does: Triggers GitHub Actions docker-image.yml for each final (non-RC) image:

  • apache/gravitino:{VERSION}
  • apache/gravitino-iceberg-rest:{VERSION}
  • apache/gravitino-lance-rest:{VERSION}
  • apache/gravitino-mcp-server:{VERSION}
  • apache/gravitino-playground:trino-{TRINO_VER}-gravitino-{VERSION}

The --state-key docker-final flag causes publish-docker.sh to write docker-final.done (distinct from the RC docker.done written in stage 5). RELEASE_STATE_DIR is set explicitly so both state files land in the same .release-state/{RC_TAG}/ directory.

Always offer --dry-run first before triggering any real workflow dispatches.

Monitor progress: https://github.com/apache/gravitino/actions/workflows/docker-image.yml


Stage 8: release-note

Required env vars: (none — read-only GitHub API calls via gh)

What it does:

  1. Fetches all issues labelled with the release version (label format: {VERSION}, e.g. 1.2.1):
    gh issue list --repo apache/gravitino \
      --label "${RELEASE_VERSION}" \
      --state all \
      --limit 500 \
      --json number,title,assignees,labels,url
    
  2. Asks the user to describe 3–5 key features/themes for the Highlights section before generating the draft.
  3. Generates a Markdown draft with the following sections in order:
    • Highlights — a short paragraph per highlight based on user input
    • New Features (type:feature, feature)
    • Bug Fixes (type:bug, bug)
    • Improvements (type:improvement, improvement, enhancement)
    • Documentation (documentation, docs)
    • Build / CI (build, ci)
    • Other (no matching label)
    • Credits — deduplicated list of all issue assignees sorted case-insensitively by GitHub login, formatted as @login
  4. Displays the draft for review, then saves to: $RELEASE_SCRIPTS_DIR/gravitino-{VERSION}-release-notes.md

Stage 9: github-release

Every past release has a GitHub release page carrying the same artifacts as dist/release. Nothing in dev/release/ creates it.

Independent of the svn mv. It needs only the pushed v{VERSION} tag and the RC artifacts, so it can be done while waiting on PMC karma for dist/release.

Artifacts: export the RC directory into a clean directory and upload exactly what is in it. Do not glob the release working directory — that also holds the Python sdists, which are not part of the ASF distribution.

mkdir -p ~/v{VERSION}-assets && cd ~/v{VERSION}-assets
svn export --force https://dist.apache.org/repos/dist/dev/gravitino/v{VERSION}-rc{RC} .
ls | wc -l                   # note this count; the release page must end up matching it
shasum -a 512 -c *.sha512    # all must print OK

Create it:

gh release create "v{VERSION}" -R apache/gravitino \
  --title "Apache Gravitino {VERSION} Release Notes" \
  --notes-file notes.md \
  *.tar.gz *.tar.gz.asc *.tar.gz.sha512

Use --draft if the release notes are still in review, then gh release edit "v{VERSION}" --draft=false to publish.

Verify the asset count, do not trust the exit code:

gh release view "v{VERSION}" -R apache/gravitino --json assets --jq '.assets|length'   # must match the dist count above

A partial upload still reports success and leaves the release missing its signatures. If assets are missing, use gh release upload --clobber rather than re-running create, which fails on an existing release.

Body: the same content as the release-note stage, plus a **Full Changelog:** [v{PREV}...v{VERSION}](https://github.com/apache/gravitino/compare/v{PREV}...v{VERSION}) line and a ## Credits section listing contributors as @login.


Error Handling

When a script fails:

  1. Read the corresponding .log file and show the user the last 30 lines
  2. Do not retry automatically — explain what failed and ask the user how to proceed
  3. The .done file will not have been written (only written on success)
  4. After the user fixes the issue, they can re-run the same stage
SymptomLikely causeAction
svn: E170013Wrong ASF password or expired authRe-export ASF_PASSWORD and retry
gpg: signing failedWrong passphrase or key not in keyringCheck gpg --list-secret-keys
twine upload 403Expired PYPI_API_TOKENRegenerate token on pypi.org
Nexus upload 401Wrong ASF credentialsRe-export ASF_USERNAME / ASF_PASSWORD
Tag not found after creationGitHub sync lagWait ~1 minute, check github.com manually
docker.done not writtenBad GH_TOKEN or PUBLISH_DOCKER_TOKENCheck gh auth status and token scopes

Testing

To test the skill without any real build, publish, or git operations, use the mock scripts in dev/release/mock/.

The mock scripts:

  • Accept identical flags and env vars as the real scripts
  • Validate all credentials exactly as the real scripts do — ASF_PASSWORD, GPG_PASSPHRASE, PYPI_API_TOKEN, GH_TOKEN, DOCKER_USERNAME, and PUBLISH_DOCKER_TOKEN are all required and checked
  • Use the real release-util.sh for state management — guard checks and .done files behave exactly as in production
  • Print what each stage would do instead of executing it
  • Support MOCK_FAIL_STAGE=<stage> to simulate a failure at any stage and test error handling

Invoking mock mode

When the user requests mock mode at Step 4 of the Session Start Protocol, set RELEASE_SCRIPTS_DIR to the mock/ subdirectory:

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

All stage commands then become e.g. "$RELEASE_SCRIPTS_DIR/do-release.sh" -s tag -y ... Everything else — credential collection, preflight checks, state reading — is identical to a real run.

Test scenarios

ScenarioHow to trigger
Full happy path (all 6 stages)Run all stages in mock mode; verify all .done files are written
Resume from partial statePre-create some .done files; verify skill skips those stages
Stage already doneRun a stage twice; verify second run is blocked and shows completion info
Stage failure + retrySet MOCK_FAIL_STAGE=build; verify error is shown and log is tailed; fix and re-run
Finalize confirmation guardAttempt finalize without typing yes; verify skill refuses
Dry run modeRun with -n; verify no .done files are written
Missing secretUnset ASF_PASSWORD; verify skill prompts before running
Preflight checksgh calls run against the real repo (read-only — safe in mock mode)

Rules

  1. Never display or log secrets — mask passwords, passphrases, and tokens in all output.
  2. Always use -y mode — do-release.sh requires interactive input without it; an agent cannot respond to prompts.
  3. Show state at the start of every session — the user must always know what has been done.
  4. Guard finalize with explicit confirmation — it affects public infrastructure and is irreversible.
  5. Respect .done files — never delete or bypass them without the user's explicit instruction.
  6. Always offer --dry-run before any publishing step the user hasn't run before in this session.
  7. Run preflight before tag — always run the two preflight checks before the tag stage starts.

Installation

Claude Code, GitHub Copilot CLI, and OpenClaw all manage skills as directories containing a SKILL.md file. The skill is packaged as agent-skills/gravitino-release/ in the Gravitino repo — copy the whole directory to install.

Claude Code and GitHub Copilot CLI share the same .claude/ directory.

# Claude Code / GitHub Copilot CLI — global (available in all projects)
cp -r agent-skills/gravitino-release ~/.claude/skills/

# Claude Code / GitHub Copilot CLI — project-local (available only inside this repo)
cp -r agent-skills/gravitino-release .claude/skills/

# OpenClaw — global
cp -r agent-skills/gravitino-release ~/.openclaw/workspace/skills/

# OpenClaw — project-local
cp -r agent-skills/gravitino-release .openclaw/workspace/skills/

Invoke with /gravitino-release. No local clone of the Gravitino repository is needed — the skill downloads the release scripts automatically via gh.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

trino-test

無料概要あり

GravitinoプロジェクトのTrino統合テストを実行・調査するためのスキルです。コネクターやTrinoのバージョン、テストセットを指定して動作を確認し、SQLテストと期待結果の追加・修正も進められます。

  • Trino統合テストを一括実行したいとき
  • 特定コネクターやカタログを試したいとき
  • Trinoのバージョン別に動作を確認したいとき
apache/gravitino3,3372026年10月29日 更新

apache のスキルをすべて見る

このスキルの問題を報告する