Helm Chart Release / release-chart (push) Successful in 5s
「Registry 発行済み」と「タグ/リリース作成」が同一フラグに束ねられていたため、 タグ push だけ失敗しても回復できなかった。各成果物を個別に冪等チェックし、 不足分だけを作る構造に変更。途中失敗しても次の push で自己修復する。 タグ有無は git ls-remote でリモート基準に確認。
175 lines
7.2 KiB
YAML
175 lines
7.2 KiB
YAML
# .gitea/workflows/helm-release.yaml
|
||
# -------------------------------------------------------------------------
|
||
# secret-manager 用のチャート公開ワークフロー。
|
||
#
|
||
# 他リポジトリの「毎 push で無条件公開」する共通版とは異なり、この版は
|
||
# 3 つのリリース成果物を **それぞれ独立に冪等チェック** する:
|
||
#
|
||
# 1. Package Registry ... `Chart.yaml` の version が未登録なら発行
|
||
# 2. Git タグ v<version> ... リモートに無ければ作成して push
|
||
# 3. Gitea リリース ... 同名リリースが無ければ作成(tgz 添付)
|
||
#
|
||
# 独立チェックにしている理由: いずれかのステップだけ失敗しても、次の push で
|
||
# 不足分だけが再実行されて自己修復する(例: registry 発行は成功したがタグ
|
||
# push が権限エラーで失敗 → 次回 push でタグだけ作成される)。
|
||
# どれも不要なら全ステップが no-op(README や examples だけの変更で発火しても
|
||
# リリースは発生しない)。
|
||
# -------------------------------------------------------------------------
|
||
name: Helm Chart Release
|
||
|
||
on:
|
||
push:
|
||
branches:
|
||
- main
|
||
- master
|
||
paths:
|
||
- 'Chart.yaml'
|
||
- 'values.yaml'
|
||
- 'values.schema.json'
|
||
- 'templates/**'
|
||
- '.gitea/workflows/helm-release.yaml'
|
||
workflow_dispatch:
|
||
|
||
env:
|
||
REGISTRY_URL: https://git.cafepieters.com
|
||
OWNER: helmchart
|
||
|
||
jobs:
|
||
release-chart:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v3
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- name: Install Helm
|
||
uses: azure/setup-helm@v3
|
||
with:
|
||
version: 'v3.12.0'
|
||
|
||
- name: Ensure jq
|
||
run: |
|
||
command -v jq >/dev/null 2>&1 || { apt-get update -qq && apt-get install -y -qq jq; }
|
||
jq --version
|
||
|
||
- name: Get chart info
|
||
id: info
|
||
run: |
|
||
set -e
|
||
CHART_NAME=$(grep '^name:' Chart.yaml | head -1 | sed 's/^name:[[:space:]]*//; s/"//g; s/[[:space:]]*$//')
|
||
CHART_VERSION=$(grep '^version:' Chart.yaml | head -1 | sed 's/^version:[[:space:]]*//; s/"//g; s/[[:space:]]*$//')
|
||
echo "name=${CHART_NAME}" >> $GITHUB_OUTPUT
|
||
echo "version=${CHART_VERSION}" >> $GITHUB_OUTPUT
|
||
echo "Chart: ${CHART_NAME} v${CHART_VERSION}"
|
||
|
||
- name: Validate chart
|
||
run: helm lint --strict .
|
||
|
||
- 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)
|
||
if [ "${FOUND:-0}" -gt 0 ]; then REG=false; else REG=true; 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.any_needed == 'true'
|
||
run: |
|
||
set -e
|
||
helm package .
|
||
CHART_FILE=$(ls "${{ steps.info.outputs.name }}"-*.tgz | head -1)
|
||
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.registry_needed == 'true'
|
||
run: |
|
||
set -e
|
||
curl --fail-with-body \
|
||
-u "${{ secrets.REGISTRY_USER }}:${{ secrets.REGISTRY_TOKEN }}" \
|
||
-X POST \
|
||
--upload-file "${CHART_FILE}" \
|
||
"${REGISTRY_URL}/api/packages/${OWNER}/helm/api/charts"
|
||
echo "✅ Published ${CHART_FILE} to Package Registry"
|
||
|
||
- name: Create Gitea Release
|
||
if: steps.check.outputs.release_needed == 'true'
|
||
env:
|
||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||
run: |
|
||
set -e
|
||
VERSION="${{ steps.info.outputs.version }}"
|
||
NAME="${{ steps.info.outputs.name }}"
|
||
PACKAGE_FILE="${NAME}-${VERSION}.tgz"
|
||
|
||
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 [ -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: |
|
||
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 "ℹ️ v${V} は registry / タグ / リリース すべて揃っています。処理なし。"
|
||
echo " 新バージョンを出すには Chart.yaml の version / appVersion を上げて push。"
|
||
fi
|