From 13cb27a5ecb1b273fcafa3f708f4e3a923799aa2 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 13:36:34 +0900 Subject: [PATCH] =?UTF-8?q?chore:=20helm-release=20=E3=81=AE=E3=83=AA?= =?UTF-8?q?=E3=83=AA=E3=83=BC=E3=82=B9=E5=88=A4=E5=AE=9A=E3=82=92=20regist?= =?UTF-8?q?ry/tag/release=20=E3=81=AE3=E7=8B=AC=E7=AB=8B=E3=83=95=E3=83=A9?= =?UTF-8?q?=E3=82=B0=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 「Registry 発行済み」と「タグ/リリース作成」が同一フラグに束ねられていたため、 タグ push だけ失敗しても回復できなかった。各成果物を個別に冪等チェックし、 不足分だけを作る構造に変更。途中失敗しても次の push で自己修復する。 タグ有無は git ls-remote でリモート基準に確認。 --- .gitea/workflows/helm-release.yaml | 126 ++++++++++++++++------------- CLAUDE.md | 24 ++++++ README.md | 14 +++- 3 files changed, 102 insertions(+), 62 deletions(-) diff --git a/.gitea/workflows/helm-release.yaml b/.gitea/workflows/helm-release.yaml index 9146dda..53e379e 100644 --- a/.gitea/workflows/helm-release.yaml +++ b/.gitea/workflows/helm-release.yaml @@ -3,11 +3,17 @@ # secret-manager 用のチャート公開ワークフロー。 # # 他リポジトリの「毎 push で無条件公開」する共通版とは異なり、この版は -# 「Chart.yaml の version が Package Registry に未公開のときだけリリースする」。 -# 既に同じバージョンが公開済みなら何もしない(README や examples だけの -# 変更で push してもリリースは発生しない)。 +# 3 つのリリース成果物を **それぞれ独立に冪等チェック** する: # -# リリース = Package Registry への発行 + Git タグ + Gitea リリース(tgz 添付)。 +# 1. Package Registry ... `Chart.yaml` の version が未登録なら発行 +# 2. Git タグ v ... リモートに無ければ作成して push +# 3. Gitea リリース ... 同名リリースが無ければ作成(tgz 添付) +# +# 独立チェックにしている理由: いずれかのステップだけ失敗しても、次の push で +# 不足分だけが再実行されて自己修復する(例: registry 発行は成功したがタグ +# push が権限エラーで失敗 → 次回 push でタグだけ作成される)。 +# どれも不要なら全ステップが no-op(README や examples だけの変更で発火しても +# リリースは発生しない)。 # ------------------------------------------------------------------------- name: Helm Chart Release @@ -60,31 +66,42 @@ jobs: - name: Validate chart run: helm lint --strict . - - name: Check whether this version is already released + - name: Decide what is missing (registry / tag / release) id: check + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} run: | set -e NAME="${{ steps.info.outputs.name }}" VERSION="${{ steps.info.outputs.version }}" + TAG="v${VERSION}" + # --- 1. Package Registry --- helm repo add cafepieters "${REGISTRY_URL}/api/packages/${OWNER}/helm" \ --username "${{ secrets.REGISTRY_USER }}" \ --password "${{ secrets.REGISTRY_TOKEN }}" >/dev/null 2>&1 || true helm repo update cafepieters >/dev/null 2>&1 || true - FOUND=$(helm search repo "cafepieters/${NAME}" --version "${VERSION}" --output json 2>/dev/null | jq 'length' 2>/dev/null || echo 0) - echo "Registry entries for ${NAME} ${VERSION}: ${FOUND}" + if [ "${FOUND:-0}" -gt 0 ]; then REG=false; else REG=true; fi - if [ "${FOUND:-0}" -gt 0 ]; then - echo "release_needed=false" >> $GITHUB_OUTPUT - echo "✅ v${VERSION} は既にリリース済み。処理をスキップします。" - else - echo "release_needed=true" >> $GITHUB_OUTPUT - echo "🆕 v${VERSION} は未リリース。リリースを実行します。" - fi + # --- 2. Git タグ(リモート基準)--- + if [ -n "$(git ls-remote --tags origin "refs/tags/${TAG}" 2>/dev/null)" ]; then TAG_NEEDED=false; else TAG_NEEDED=true; fi + + # --- 3. Gitea リリース --- + REL_ID=$(curl -s -H "Authorization: token ${GITEA_TOKEN}" \ + "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/tags/${TAG}" | jq -r '.id // empty') + if [ -n "${REL_ID}" ]; then REL=false; else REL=true; fi + + if [ "$REG" = "true" ] || [ "$TAG_NEEDED" = "true" ] || [ "$REL" = "true" ]; then ANY=true; else ANY=false; fi + + echo "registry_needed=${REG}" >> $GITHUB_OUTPUT + echo "tag_needed=${TAG_NEEDED}" >> $GITHUB_OUTPUT + echo "release_needed=${REL}" >> $GITHUB_OUTPUT + echo "any_needed=${ANY}" >> $GITHUB_OUTPUT + echo "registry=${REG} / tag=${TAG_NEEDED} / release=${REL} (${NAME} ${TAG})" - name: Package chart - if: steps.check.outputs.release_needed == 'true' + if: steps.check.outputs.any_needed == 'true' run: | set -e helm package . @@ -92,8 +109,19 @@ jobs: echo "CHART_FILE=${CHART_FILE}" >> $GITHUB_ENV echo "Packaged: ${CHART_FILE}" + - name: Create Git tag + if: steps.check.outputs.tag_needed == 'true' + run: | + set -e + VERSION="${{ steps.info.outputs.version }}" + git config user.name "Claude" + git config user.email "claude@cafepieters.com" + git tag -a "v${VERSION}" -m "Release ${VERSION}" || true + git push origin "v${VERSION}" + echo "Git tag v${VERSION} pushed" + - name: Publish to Gitea Package Registry - if: steps.check.outputs.release_needed == 'true' + if: steps.check.outputs.registry_needed == 'true' run: | set -e curl --fail-with-body \ @@ -103,21 +131,6 @@ jobs: "${REGISTRY_URL}/api/packages/${OWNER}/helm/api/charts" echo "✅ Published ${CHART_FILE} to Package Registry" - - name: Create Git tag - if: steps.check.outputs.release_needed == 'true' - run: | - set -e - VERSION="${{ steps.info.outputs.version }}" - git config user.name "Claude" - git config user.email "claude@cafepieters.com" - if git rev-parse "v${VERSION}" >/dev/null 2>&1; then - echo "Tag v${VERSION} already exists, skipping" - else - git tag -a "v${VERSION}" -m "Release ${VERSION}" - git push origin "v${VERSION}" - echo "Git tag v${VERSION} created" - fi - - name: Create Gitea Release if: steps.check.outputs.release_needed == 'true' env: @@ -128,37 +141,34 @@ jobs: NAME="${{ steps.info.outputs.name }}" PACKAGE_FILE="${NAME}-${VERSION}.tgz" - EXISTING=$(curl -s -H "Authorization: token ${GITEA_TOKEN}" \ - "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/tags/v${VERSION}" | jq -r '.id // empty') + RELEASE_ID=$(curl -s -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"v${VERSION}\",\"name\":\"v${VERSION}\",\"body\":\"secret-manager Helm Chart v${VERSION}\"}" \ + "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases" | jq -r '.id') - if [ -n "${EXISTING}" ]; then - echo "Release v${VERSION} already exists (id=${EXISTING}), skipping" - else - RELEASE_ID=$(curl -s -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/json" \ - -d "{\"tag_name\":\"v${VERSION}\",\"name\":\"v${VERSION}\",\"body\":\"secret-manager Helm Chart v${VERSION}\"}" \ - "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases" | jq -r '.id') - - curl -s -X POST \ - -H "Authorization: token ${GITEA_TOKEN}" \ - -H "Content-Type: application/gzip" \ - --data-binary "@${PACKAGE_FILE}" \ - "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${PACKAGE_FILE}" - - echo "Gitea release v${VERSION} created with asset ${PACKAGE_FILE}" + if [ -z "${RELEASE_ID}" ] || [ "${RELEASE_ID}" = "null" ]; then + echo "❌ リリース作成に失敗しました" >&2 + exit 1 fi + curl -s -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/gzip" \ + --data-binary "@${PACKAGE_FILE}" \ + "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${PACKAGE_FILE}" + + echo "Gitea release v${VERSION} created with asset ${PACKAGE_FILE}" + - name: Summary run: | - if [ "${{ steps.check.outputs.release_needed }}" = "true" ]; then - echo "================================" - echo "✅ Released secret-manager v${{ steps.info.outputs.version }}" - echo "================================" - echo "helm repo add cafepieters ${REGISTRY_URL}/api/packages/${OWNER}/helm" - echo "helm repo update" - echo "helm upgrade --install secrets cafepieters/secret-manager" + REG="${{ steps.check.outputs.registry_needed }}" + TAG="${{ steps.check.outputs.tag_needed }}" + REL="${{ steps.check.outputs.release_needed }}" + V="${{ steps.info.outputs.version }}" + if [ "$REG" = "true" ] || [ "$TAG" = "true" ] || [ "$REL" = "true" ]; then + echo "✅ secret-manager v${V} — registry:${REG} tag:${TAG} release:${REL} を処理しました" else - echo "ℹ️ No release: v${{ steps.info.outputs.version }} is already published." - echo " バージョンを上げたい場合は Chart.yaml の version / appVersion を更新して push してください。" + echo "ℹ️ v${V} は registry / タグ / リリース すべて揃っています。処理なし。" + echo " 新バージョンを出すには Chart.yaml の version / appVersion を上げて push。" fi diff --git a/CLAUDE.md b/CLAUDE.md index 9736cef..5bf746d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -61,6 +61,30 @@ ## チャート改修履歴 +### helm-release.yaml のリリース判定を3系統に分離 + v0.1.0 タグ補完(2026-09-08) + +**症状**: Git タグ `v0.1.0` がリモートに存在しなかった(Registry には +`secret-manager-0.1.0.tgz` は発行済み)。 + +**原因**: 初回リリース(run #1 / `f374cd2`)時点の `helm-release.yaml` は +共通版のコピー(タグ作成ステップ無し)だった。タグ作成ステップを持つ現行版に +差し替えたのは run #2 だが、その時点で `0.1.0` は既に Registry 登録済みのため +`release_needed=false` となり、タグ作成を含む全ステップがスキップされていた。 += 「Registry 発行済み」と「タグ/リリース作成」が同一フラグに束ねられており、 +一方だけ欠けた状態を回復できない構造だった。 + +**修正内容**: +- `helm-release.yaml` の判定を `registry_needed` / `tag_needed` / `release_needed` + の3独立フラグに分離。各成果物を個別に冪等チェックし、不足分だけを作る。 + 途中のステップだけ失敗しても次の push で自己修復する。 +- タグ有無は `git ls-remote --tags` でリモート基準に確認。 +- 欠けていた `v0.1.0` タグを `f374cd2`(Registry の 0.1.0 tgz と同じツリー)に + 対して手動で作成・push(過去分の履歴補完。Gitea リリースは 0.1.0 が既知不具合 + バージョンのため作らない)。 + +**対象ファイル**: `.gitea/workflows/helm-release.yaml`, `README.md`, `CLAUDE.md` +(+ リモートタグ `v0.1.0` を追加) + ### values.schema.json の $schema 行を削除(2026-09-08, v0.1.1) **症状**: 一部のデプロイ環境(新しめの JSON Schema バリデータを内蔵する Helm / Argo CD / diff --git a/README.md b/README.md index e8d252b..624a789 100644 --- a/README.md +++ b/README.md @@ -312,10 +312,16 @@ Secret 更新時に自動でローリング再起動されます。 `.gitea/workflows/helm-release.yaml` の 1 本のみ。`main` への push(`Chart.yaml` / `values.yaml` / `values.schema.json` / `templates/**` 変更時)と手動実行で発火し、 -`helm lint --strict` → **現在の `version` が Package Registry に未公開のときだけ** -リリースする(公開済みなら何もしない。README・examples だけの変更ではリリースされない)。 -リリース内容は **Package Registry への発行 + Git タグ `v` + Gitea リリース -(`.tgz` 添付)**。 +`helm lint --strict` のあと、次の 3 つの成果物を **それぞれ独立に冪等チェック**して、 +不足しているものだけを作る: + +1. **Package Registry** — `Chart.yaml` の `version` が未登録なら `.tgz` を発行 +2. **Git タグ `v`** — リモートに無ければ作成して push +3. **Gitea リリース** — 同名リリースが無ければ作成(`.tgz` 添付) + +3 つすべて揃っていれば何もしない(README・examples だけの変更ではリリースされない)。 +独立チェックなので、いずれかのステップだけ失敗しても次の push で不足分だけが +再実行されて自己修復する。 > **上流イメージの週次自動追従は行わない** — 他チャート(phpfpm・n8n 等)は > `image-update-and-release.yaml` で Docker Hub の最新イメージを毎週チェックしバージョンを