This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Moderna utsläppsstrategier med GitHub actions
Thursday, 04 December 2025
Kernprincipen: : gör släppen snabba och smärtfria, , och du kommer att släppa mer ofta. Detta är viktigt för agil utveckling. - snabb , tillförlitliga inplantningar skapar den snabba återkopplingsloop du behöver. ♫ . ♫ När inplanting är skrämmande eller långsamt ♫
Den här handboken omfattar de utsläppsstrategier som jag använder i produktionen, från enkel tag, -, till multi, -, paket-monorepopublicering och .. Alla exempel kommer från verkliga GitHub-aktioner arbetsflöden i detta arkiv.
Release strategier på en titt
Innan man dyker in i detaljer
| Strategin | bäst för | komplexitet | 3 | vanliga i | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Tag-baserad | Applikationer , explicita utsläpp | låga | uppstartar | , | solo-devs | МSK5 | mogna lag | ||||
| Filiala-baserad | Kontinuett utplacering | lågt | Start-up | МSK3 | snabbt | - | rörande lag | ||||
| GitFlow | Regulerade versioner , flera versioner | Hög | |||||||||
| Trunk-based + Feature flags | Höga -hastighetsteams | Medel | stora tekniker | МSK4 | mogna nystartare | ||||||
| Monorepo multi-package | Bibliotekar , gemensama kodexbaser | mellan | МSK3 | Plattenteams |
Vad fungerar var
Startups & Små lag: Börja med tag-baserat eller ramverkt -baserad utnyttjandeM SK3 Säg det enkelt ♫ - du kan alltid lägga till komplexitet senare ♫. ♫ Trunk ♫
Företagande: Åtminstone kräver GitFlow eller liknande för noggrannhet , revīzijasspår M SK2 och utsläppshantering . Flera miljöer
Enkel utvecklare: etikett - baserat är idealt. trycka på etiketten
Platform/Library Teams: Bra monorepo-strategier med oberoende versionering per paket
Tag-Based Deployment
Den enklaste och mest tillförlitliga strategin
Miljötargetering
on:
push:
tags:
- 'release-*' # Production
- 'local-*' # Dev environment
- name: Build Docker image
run: |
TAG_NAME=${GITHUB_REF#refs/tags/}
if [[ "$TAG_NAME" == local-* ]]; then
docker build -t myapp:local .
else
docker build -t myapp:latest -t myapp:$(date +%s) .
fi
Varför det fungerar: Enkel mental modell
# Deploy to production
git tag release-v2024.12.01 && git push origin release-v2024.12.01
# Deploy to dev
git tag local-feature-test && git push origin local-feature-test
Multi-Versionering av paket
För monorepos med flera publicierbara paket, använda tagpräfixer för att identifiera vilket paket man ska släppa
# Different workflows, different tag patterns
# umami-net.yml
on:
push:
tags: ['umamiv*.*.*'] # e.g., umamiv1.0.5
# fetchextension.yml
on:
push:
tags: ['fetchextension-v*.*.*'] # e.g., fetchextension-v1.2.0
Extrahera versionen och använda den hela tiden:
- name: Extract version
run: echo "VERSION=${GITHUB_REF#refs/tags/umamiv}" >> $GITHUB_OUTPUT
- name: Build & Pack
run: |
dotnet build -c Release -p:Version=${{ steps.version.outputs.VERSION }}
dotnet pack -c Release -p:PackageVersion=${{ steps.version.outputs.VERSION }}
För automatiska versioneringar, Minver beräknar versioner från Git tags:
<PackageReference Include="MinVer" Version="6.0.0" PrivateAssets="all" />
<PropertyGroup>
<MinVerTagPrefix>umamiv</MinVerTagPrefix>
</PropertyGroup>
Filiala-baserad utpostning
Deploy automatiskt när koden landar på specifika grannar
on:
push:
branches: [main] # → Production
# branches: [develop] # → Staging
Förmågor: Inga manuella steg Olyckor: Oavsiktliga utpostningar möjliga , mindre explicit historia
Jag använder ett hybridt tillvägagångssätt - bygga på branch-puss | ( | CI-bekräftelse |), | men publicera bara på tag |
on:
push:
tags: ['scheduler-*']
branches: [main, local]
jobs:
build:
# Always build
publish:
if: startsWith(github.ref, 'refs/tags/') # Only publish on tags
Auto-Aktualiseringar med observatori
För självständiga utpostningar Observationstorn drar automatiskt upp nya bilder:
services:
app:
image: myapp:latest
labels:
- "com.centurylinklabs.watchtower.enable=true"
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 300 # Check every 5 minutes
Deploymentflödet: Att trycka på tag → GitHub Actions bygger | | → | Springa till registret |
Kwaliteitssteg
Vinniga utspegningar är värdelösa om du utspegs bugs. Varje arbetsflöde bör inkludera grindar:
- name: Run tests
run: dotnet test --configuration Release
- name: Build
run: dotnet build --configuration Release
# Tests or build fail → workflow stops → no publish
För multi- -- -frameworkpaket - , -bygg alla mål - :
- run: dotnet build -c Release --framework net8.0
- run: dotnet build -c Release --framework net9.0
Passwordless Publishing med OIDC
Modernt tillvägagångssätt - inga hemligheter för att rotera , inga nycklar för att läcka
permissions:
id-token: write
contents: read
- uses: NuGet/login@v1
with:
user: 'myusername'
- run: dotnet nuget push *.nupkg --api-key ${{ steps.login.outputs.NUGET_API_KEY }}
GitHub utbyter sin OIDC-token för en kort NuGet API-kliv
Tillförselkedjorskedjan
Artifaktbescheinigunger bevisa att dina artefakter är byggda i CI, inte manipulerade med
permissions:
id-token: write
attestations: write
- uses: docker/build-push-action@v6
id: push
with:
push: true
tags: myapp:latest
- uses: actions/attest-build-provenance@v2
with:
subject-name: index.docker.io/myuser/myapp
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
Konsumenter ser med: gh attestation verify oci://index.docker.io/myuser/myapp:latest --owner myuser
Detta uppnår SLSA-nivå 2. För nivån 3, använda återanvändbara arbetsflöden.
Föreställ omgivningar
Teams behöver intressenter för att förutse förändringar innan de går samman
Enterprise-metoden - Filialen -grundade förfogningsmiljöer
on:
pull_request:
types: [opened, synchronize]
- run: |
BRANCH=$(echo ${{ github.head_ref }} | sed 's/[^a-zA-Z0-9]/-/g')
docker build -t myapp:preview-$BRANCH .
# Deploy to k8s namespace, cloud platform, etc.
Startup/solo-metod - Tunnelera din lokala maskin
# Cloudflare Tunnel (free)
cloudflared tunnel run --url http://localhost:5000 my-preview
# → https://my-preview.cfargotunnel.com
Eller använda Kabelvakt VPN för inre team-utgång till din dev-maskin.
Praktiska tips
Tag städ: Git-tag står kvar för alltid
git tag -d old-test-tag # Delete local
git push origin :refs/tags/old-test-tag # Delete remote
Nameringskonventioner: Var konsekvent
release-YYYY.MM.DDför produktionlocal-feature-nameför devpackagev1.2.3för bibliotek
Hemligheter: Lagera i GitHub Secrets, aldrig i koden . Erforderliga hemligheter vanligtvis
DOCKER_HUB_ACCESS_TOKENNUGET_API_KEY( eller använda OIDCNPM_TOKEN
Monorepo-utveckling: Använda projektreferenser under utvecklingen , byta till paketreferens för användningskontroll
<ProjectReference Include="..\MyLib\MyLib.csproj" />
<!-- <PackageReference Include="MyLib" Version="1.0.0" /> -->
Gå till Kubernetes
Samma principer , olika verktyg
| Docker Compose | Kubernetes | ||
|---|---|---|---|
| Tydtorn | ArgoCD / Flux | ||
| docker | |||
| Kontineruppstartning | Rollingsoperation | ||
| Handlig rollback | GitOps rollback |
sammanfattning
- Börja enkelt: Tag-based deployment covers most needs
- Lägg till komplexitet när det behövs: Filialen -baserade, flertalig
- Automatiserade kvalitet-grindar: Test måste klaras innan de publiceras
- Aktivera rollback: Timestamped-tag eller GitOps historia
- Bevara din pipeline: OIDC för hemligheter
- Matcha din kontext: Solo dev ≠ startup ≠ enterprise
De arbetsflödena som visas här körs i detta arkiv - check .github/workflows/ för kompletta implementeringar.
Kom ihåg: Vinniga implementeringar är grunden till agil utveckling . Investera i din utsläppskedjor tidigt