Files
claude-code/.gitea/workflows/image-update-and-release.yaml
T
claude 1bd0fec23a
Helm Chart Release / release-chart (push) Successful in 12s
Build Session Image / build-push (push) Successful in 2m15s
feat: Alpine ベースの Claude Code リモート実行 Helm チャート初版 (v2.1.259)
gateway(nginx) + manager(python 標準ライブラリ) + セッションごとの使い捨て Pod +
reaper CronJob の構成。ブラウザ(PC/スマホ)からアクセスし、セッション単位で
独立した Alpine コンテナに Git リポジトリ(GitHub/Gitea など)をチェックアウトして
編集・検証・プッシュする。無操作が続いたセッションは Pod ごと自動破棄。

- セキュリティ: セッション NS 分離 / restricted PodSecurity / RBAC はセッション NS の
  pods,services のみの Role / セッション Pod は SA トークン非マウント・非 root・
  readOnlyRootFilesystem・drop ALL caps・seccomp / NetworkPolicy で egress を
  DNS+HTTPS+SSH に限定 / Git ホスト allow-list / ResourceQuota+LimitRange
- ライフサイクル: idleTimeout(Pod 内ウォッチドッグ + manager 回収) / maxLifetime
  (activeDeadlineSeconds) / maxSessions / 予備の孤児掃除 CronJob
- 認証: token(既定) / basic / forward(外部SSO) / none。WebSocket は Cookie トークン
- Claude 認証: ANTHROPIC_API_KEY または CLAUDE_CODE_OAUTH_TOKEN
- CI: helm-release.yaml(未リリース版のみ tag+release+publish) /
  image-update-and-release.yaml(週次 npm 追従) / session-image.yaml(multi-arch build)
- files/ 実体を .Files.Get で ConfigMap 化。helm lint / template 検証済み
2026-09-03 08:10:12 +09:00

189 lines
8.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Update Versions and Release Helm Chart
# 毎週月曜 3:00 AM JST(日曜 18:00 UTC)に実行。
# - 主アプリ = Claude Code CLI(npm: @anthropic-ai/claude-code)の最新版を確認
# - base image = gateway(nginx) / manager(python) の最新 Alpine タグを確認
# - 主アプリが更新: values.yaml / Chart.yaml / README 履歴を更新しコミット → タグ + Gitea リリース + チャート publish
# - base image のみ更新: values.yaml を更新してコミットのみ(リリースなし)
#
# セッションイメージのビルドは session-image.yaml が担当する(このワークフローが
# Chart.yaml を push した結果として発火する)。
on:
schedule:
- cron: '0 18 * * 0'
workflow_dispatch:
env:
REGISTRY_URL: https://git.cafepieters.com
OWNER: helmchart
jobs:
update-and-release:
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.16.4'
- name: Ensure jq
run: command -v jq >/dev/null 2>&1 || (sudo apt-get update -qq && sudo apt-get install -y -qq jq)
- name: Check Claude Code (npm) version
id: cc
run: |
set -e
CURRENT=$(grep '^appVersion:' Chart.yaml | sed 's/.*"\(.*\)".*/\1/')
LATEST=$(curl -s --retry 3 --retry-delay 5 \
"https://registry.npmjs.org/@anthropic-ai/claude-code/latest" | jq -r '.version // empty')
echo "Current: $CURRENT / npm latest: ${LATEST:-not found}"
if [ -n "$LATEST" ]; then
HIGHER=$(printf '%s\n%s' "$CURRENT" "$LATEST" | sort -V | tail -1)
if [ "$HIGHER" != "$LATEST" ] && [ "$CURRENT" != "$LATEST" ]; then
echo "Warning: npm latest ($LATEST) < current ($CURRENT). Skipping."
LATEST="$CURRENT"
fi
else
LATEST="$CURRENT"
fi
echo "current=$CURRENT" >> $GITHUB_OUTPUT
echo "latest=$LATEST" >> $GITHUB_OUTPUT
- name: Check base image (nginx / python) tags
id: base
run: |
set -e
NGINX_CUR=$(grep -A3 'gateway:' values.yaml | grep 'tag:' | head -1 | sed 's/.*"\(.*\)".*/\1/')
PY_CUR=$(grep -A3 'manager:' values.yaml | grep 'tag:' | head -1 | sed 's/.*"\(.*\)".*/\1/')
NGINX_LATEST=$(curl -s --retry 3 "https://registry.hub.docker.com/v2/repositories/nginxinc/nginx-unprivileged/tags?page_size=100" \
| jq -r '.results[].name' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+-alpine$' | sort -V | tail -1)
PY_LATEST=$(curl -s --retry 3 "https://registry.hub.docker.com/v2/repositories/library/python/tags?page_size=100&name=alpine" \
| jq -r '.results[].name' | grep -E '^3\.[0-9]+-alpine$' | sort -V | tail -1)
[ -n "$NGINX_LATEST" ] || NGINX_LATEST="$NGINX_CUR"
[ -n "$PY_LATEST" ] || PY_LATEST="$PY_CUR"
echo "nginx: $NGINX_CUR -> $NGINX_LATEST ; python: $PY_CUR -> $PY_LATEST"
echo "nginx_cur=$NGINX_CUR" >> $GITHUB_OUTPUT
echo "nginx_latest=$NGINX_LATEST" >> $GITHUB_OUTPUT
echo "py_cur=$PY_CUR" >> $GITHUB_OUTPUT
echo "py_latest=$PY_LATEST" >> $GITHUB_OUTPUT
- name: Decide
id: decide
run: |
set -e
CC=false; BASE=false
[ "${{ steps.cc.outputs.current }}" != "${{ steps.cc.outputs.latest }}" ] && CC=true
[ "${{ steps.base.outputs.nginx_cur }}" != "${{ steps.base.outputs.nginx_latest }}" ] && BASE=true
[ "${{ steps.base.outputs.py_cur }}" != "${{ steps.base.outputs.py_latest }}" ] && BASE=true
echo "cc=$CC" >> $GITHUB_OUTPUT
echo "base=$BASE" >> $GITHUB_OUTPUT
echo "update_needed=$([ "$CC" = true ] || [ "$BASE" = true ] && echo true || echo false)" >> $GITHUB_OUTPUT
- name: Update values.yaml (image tags)
if: steps.decide.outputs.update_needed == 'true'
run: |
set -e
sed -i "s|tag: \"${{ steps.base.outputs.nginx_cur }}\"|tag: \"${{ steps.base.outputs.nginx_latest }}\"|g" values.yaml
sed -i "s|tag: \"${{ steps.base.outputs.py_cur }}\"|tag: \"${{ steps.base.outputs.py_latest }}\"|g" values.yaml
if [ "${{ steps.decide.outputs.cc }}" = "true" ]; then
sed -i "s|tag: \"${{ steps.cc.outputs.current }}\"|tag: \"${{ steps.cc.outputs.latest }}\"|g" values.yaml
fi
git diff --stat values.yaml || true
- name: Update Chart.yaml (version == Claude Code version)
if: steps.decide.outputs.cc == 'true'
run: |
set -e
NEW="${{ steps.cc.outputs.latest }}"
sed -i "s/^version: .*/version: ${NEW}/" Chart.yaml
sed -i "s/^appVersion: .*/appVersion: \"${NEW}\"/" Chart.yaml
cat Chart.yaml
- name: Update README version history
if: steps.decide.outputs.cc == 'true'
run: |
set -e
NEW="${{ steps.cc.outputs.latest }}"
sed -i "/^| バージョン | Claude Code | 変更内容 |/{
n
a\| ${NEW} | ${NEW} | 自動更新 |
}" README.md
- name: Lint
if: steps.decide.outputs.update_needed == 'true'
run: helm lint .
- name: Commit
if: steps.decide.outputs.update_needed == 'true'
run: |
set -e
git config user.name "Claude"
git config user.email "claude@cafepieters.com"
if [ "${{ steps.decide.outputs.cc }}" = "true" ]; then
git add values.yaml Chart.yaml README.md
git commit -m "chore: update Claude Code to ${{ steps.cc.outputs.latest }} (nginx ${{ steps.base.outputs.nginx_latest }}, python ${{ steps.base.outputs.py_latest }})"
else
git add values.yaml
git commit -m "chore: bump base images — nginx ${{ steps.base.outputs.nginx_latest }}, python ${{ steps.base.outputs.py_latest }} (no release)"
fi
git push origin "${GITHUB_REF_NAME:-main}"
- name: Package
if: steps.decide.outputs.cc == 'true'
run: |
set -e
helm package .
echo "CHART_FILE=$(ls claude-code-*.tgz)" >> $GITHUB_ENV
- name: Git tag
if: steps.decide.outputs.cc == 'true'
run: |
set -e
V="v${{ steps.cc.outputs.latest }}"
git rev-parse "$V" >/dev/null 2>&1 && { echo "tag $V exists"; exit 0; }
git tag -a "$V" -m "Release $V"
git push origin "$V"
- name: Gitea Release
if: steps.decide.outputs.cc == 'true'
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -e
NEW="${{ steps.cc.outputs.latest }}"; V="v${NEW}"
if curl -s -H "Authorization: token ${GITEA_TOKEN}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/tags/${V}" | jq -e '.id' >/dev/null 2>&1; then
echo "release ${V} exists, skip"
else
RID=$(curl -s -X POST -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" \
-d "{\"tag_name\":\"${V}\",\"name\":\"${V}\",\"body\":\"claude-code Helm Chart ${V} — Claude Code CLI ${NEW}\"}" \
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases" | jq -r '.id')
curl --fail-with-body -X POST -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/gzip" \
--data-binary "@${CHART_FILE}" \
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/${RID}/assets?name=${CHART_FILE}"
fi
- name: Publish chart to Gitea Package Registry
if: steps.decide.outputs.cc == '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"
- name: Summary
if: always()
run: |
echo "Claude Code : ${{ steps.cc.outputs.current }} -> ${{ steps.cc.outputs.latest }} (updated: ${{ steps.decide.outputs.cc }})"
echo "nginx : ${{ steps.base.outputs.nginx_cur }} -> ${{ steps.base.outputs.nginx_latest }}"
echo "python : ${{ steps.base.outputs.py_cur }} -> ${{ steps.base.outputs.py_latest }}"
echo "release : ${{ steps.decide.outputs.cc }}"