Pipeline'da Versioning'i Tag'den Okumak
run_number sürüm değildir

github.run_number artar, geri dönmez, aynı commit'te tekrar koşunca değişir. Bunu imaj sürümü yapmak, 'kaçıncı kez koştuk'u ürün sürümü sanmaktır. Rollback '1421'e dön' diyemez; 1421 hangi SHA, hangi tag, hangi digest? Log'da kaybolur.
İki etiket
Her imaj git sha taşır. Yayın imajı ayrıca v1.8.0 taşır. SHA her commit'te var. Semver, tag push'ta var. İkisini de basıyorum. latest yok. run_number yok. Tarih damgası süs olabilir, anahtar olamaz — saat dilimi ve yeniden koşu onu da kaydırır.
name: publish
on:
push:
tags: ["v*.*.*"]
jobs:
image:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Version from tag
id: ver
run: |
TAG="${GITHUB_REF_NAME}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "semver=${TAG#v}" >> "$GITHUB_OUTPUT"
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
push: true
tags: |
ghcr.io/${{ github.repository }}/api:${{ steps.ver.outputs.semver }}
ghcr.io/${{ github.repository }}/api:${{ github.sha }}
GITHUB_REF_NAME tag işinde v1.8.0 olur. Branch işinde main olur — onu semver diye basma. Tag trigger'ı bu yüzden ayrı. git describe --tags --exact-match checkout sığsa ve tag gelmezse yalan söyler; fetch-depth: 0 veya tag event yeter.
Üç etiket, bir blob
v1.8.0 yayın. v1.8 son patch'i gösteren hareketli minor — bunu basarsam latest'in kuzeni olur, basmam. v1 hiç basmam. Hareket eden major, Pazartesi hikâyesi. SHA her commit. Pre-release v1.8.0-rc.1 ayrı kanal; üretim values'u rc çekmez.
git describe --tags sığ clone'da yalan söyler. Tag event'inde GITHUB_REF_NAME yeter. Branch'te git describe 'dirty' ve gabcdef üretir. Onu semver diye registry'ye basmak, 'sürüm' kelimesini bozar. Branch işi sadece SHA basar. Tag işi SHA + semver.
- name: Refuse floating tags
run: |
case "${GITHUB_REF_NAME}" in
v*.*.*) echo "semver ok" ;;
*) echo "not a release tag" >&2; exit 1 ;;
esac
SBOM ve imza aynı semver'i taşır. cosign sign digest imzalar. Tag'e imza bağlamak, tag kayınca imzayı sahipsiz bırakır. /version ucu semver + SHA döner. Log'daki istek, kutu, kayıt üçlüsü aynı sayıyı söyler. Biri saparsa yayın yalanıdır.
github.run_attempt yeniden koşuyu sayar, sürüm değildir. Aynı tag'i ikinci kez koşturmak aynı semver'i basmalı, aynı SHA'yı basmalı. Basmazsa registry'ye iki blob, bir isim. İkinci koşu, ilkinin üzerine yazar. Digest kaydı değişir, tag aynı kalır. Bunu 'idempotent yayın' sanmak, geri dönüşü ikinci koşunun blob'una bağlar.
Changelog'u tag'den üretiyorum: önceki tag..bu tag. run_number aralığı bir changelog değildir. git log v1.7.4..v1.8.0 okunur. git log 1390..1421 boş bir aralıktır, commit değil job sayısıdır.
- name: Pin tag to this commit
run: |
test "$(git rev-parse HEAD)" = "${GITHUB_SHA}"
test "${GITHUB_REF_NAME}" = "$(git describe --tags --exact-match)"
Tag'i insan parmağıyla basmak da run_number kadar kaygandır. v1.8.0 'ı yanlış commite yapıştırmak, kaydı zehirler. Koruma: tag job'u github.sha ile git rev-parse eşleşmesini ister. Eşleşmezse basmaz. Parmağın işi tag açmaktır, hash uydurmak değil. Hash commit'ten gelir, parmak sadece isim takar. İsim takmak, koşu numarası uydurmaktan daha az zararlıdır; yine de kapısız bırakmam.
AssemblyInformationalVersion'a aynı semver'i yazıyorum. Çalışan kutu /version ile tag'i söyler. Deploy kaydı tag + digest. Elle 'bir önceki numaraya dön' yok. Tag duruyorsa geri dönüş bir isimdir, bir tahmin değil.
Yorumlar
Yorumlar (0)
Yorumlar üyelere açık. Üye ol · Giriş yap