78 lines
4.0 KiB
YAML
78 lines
4.0 KiB
YAML
name: build
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
# CI 最後一步會 commit 回 manifests/deployment.yaml(更新
|
||
# image tag),排除這個路徑避免那次 commit 又觸發一輪新的
|
||
# build,形成無限迴圈。
|
||
paths-ignore:
|
||
- manifests/**
|
||
|
||
jobs:
|
||
build-and-push:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: Log in to Gitea container registry
|
||
# job 容器繼承了 host(OrbStack)的 ~/.docker/config.json,
|
||
# 裡面設定 credsStore: osxkeychain,但容器是 Linux 環境,
|
||
# 沒有 macOS 專屬的 docker-credential-osxkeychain 可執行
|
||
# 檔,docker login 會找不到它而失敗。移除這個 credsStore
|
||
# 設定,讓 docker login 改用純文字存憑證(寫進 job 容器
|
||
# 內的 ~/.docker/config.json,容器本身就是一次性的,跑完
|
||
# job 就銷毀,不像本機長期環境需要 Keychain 加密)。
|
||
run: |
|
||
mkdir -p ~/.docker
|
||
echo '{}' > ~/.docker/config.json
|
||
echo "${{ secrets.REGISTRY_PUSH_TOKEN }}" | docker login gitea.niq-dev.com -u "${{ gitea.actor }}" --password-stdin
|
||
|
||
- name: Build image
|
||
run: docker build -t gitea.niq-dev.com/gitea_admin/landing:${{ gitea.sha }} -t gitea.niq-dev.com/gitea_admin/landing:latest .
|
||
|
||
- name: Push image
|
||
run: |
|
||
docker push gitea.niq-dev.com/gitea_admin/landing:${{ gitea.sha }}
|
||
docker push gitea.niq-dev.com/gitea_admin/landing:latest
|
||
|
||
- name: Prune old package versions (keep newest 5)
|
||
# Gitea container registry 沒有內建的 retention 機制,每次
|
||
# push 都用 commit-sha 當 tag,不清理的話會無限累積把
|
||
# gitea PVC(10Gi)塞滿。Package API 對同一個 build 會列出
|
||
# 4 筆版本記錄:一筆 "latest"、一筆 commit-sha、兩筆
|
||
# "sha256:<digest>"(manifest digest,由 tag 指向,不是
|
||
# 獨立可清的東西)。只針對 version 是 40 字元 hex(commit
|
||
# sha 格式)的記錄做「保留最新 5 筆」,latest 永遠保留、
|
||
# sha256: 開頭的 digest 記錄不主動處理,避免誤刪或刪掉
|
||
# 還在被引用的 manifest。
|
||
run: |
|
||
curl -s -H "Authorization: token ${{ secrets.REGISTRY_PUSH_TOKEN }}" \
|
||
"https://gitea.niq-dev.com/api/v1/packages/gitea_admin/container/landing" \
|
||
| jq -r '[.[] | select(.version | test("^[0-9a-f]{40}$"))] | sort_by(.created_at) | reverse | .[5:] | .[].id' \
|
||
> /tmp/prune-ids.txt
|
||
|
||
while read -r id; do
|
||
[ -z "$id" ] && continue
|
||
echo "Deleting package version id=$id"
|
||
curl -s -X DELETE -H "Authorization: token ${{ secrets.REGISTRY_PUSH_TOKEN }}" \
|
||
"https://gitea.niq-dev.com/api/v1/packages/gitea_admin/container/landing/$id"
|
||
done < /tmp/prune-ids.txt
|
||
|
||
- name: Update manifest with new image tag and commit back to git
|
||
# 讓 Argo CD 真正偵測到「有新版本要部署」:manifests/ 裡的
|
||
# image 從固定的 :latest 改成這次 build 的 commit-sha,
|
||
# Argo CD watch 到 git diff 才會觸發 sync(deployment.yaml
|
||
# 寫死 :latest 的話,即使 push 了新 image,K8s 也不會自動
|
||
# 重新 pull,Pod 會一直跑舊版本)。用 GIT_COMMIT_TOKEN(repo
|
||
# 寫入權限,跟 REGISTRY_PUSH_TOKEN 分開,最小權限原則)推回
|
||
# main。這次 push 只改 manifests/ 底下的檔案,會被上面
|
||
# paths-ignore 排除,不會再觸發一輪新的 build。
|
||
run: |
|
||
sed -i "s|landing:latest|landing:${{ gitea.sha }}|" manifests/deployment.yaml
|
||
git config user.name "gitea-actions"
|
||
git config user.email "actions@gitea.niq-dev.com"
|
||
git add manifests/deployment.yaml
|
||
git diff --cached --quiet && exit 0
|
||
git commit -m "Deploy landing:${{ gitea.sha }}"
|
||
git push "https://gitea_admin:${{ secrets.GIT_COMMIT_TOKEN }}@gitea.niq-dev.com/gitea_admin/landing.git" HEAD:main
|