# Сучасна стратегія звільнення з діями GitHub

<!--category-- DevOps, CI/CD, GitHub Actions -->
<datetime class="hidden">2025-12-04T12:00</datetime>

**Основний принцип: швидко і безболісно вивільняйте, і ви частіше вивільняєтеся.** Це є важливим для гнучкого розвитку - швидке, надійне впровадження створює потрібний цикл швидкого зворотного зв' язку. Під час активації команди згруповують зміни, збільшують ризики. Якщо використання є нудним і автоматичним, ви часто надсилаєте малі зміни.

Цей довідник охоплює стратегії випуску, які я використовую для виробництва, від простого впровадження теґів до видання монорепо з декількома пакунками. Всі приклади взято з реального [Дії GitHub](https://docs.github.com/en/actions) працює у цьому сховищі.

[TOC]

## Стратегія звільнення на полі бою

Перш ніж почати заглиблюватись у деталі, ось як загальні стратегії порівнюються:

♪
|----------|----------|------------|-----------|
| **Заснований на мітках** applications, applications, moo dev, parse teames
| **Заснований на гілках** команди, що швидко мандрують
| **GitFlow** Терт-Тід, декілька версій, декілька.
| **Прапорці, засновані на trunk + можливості** Команди "Га-волоце," що складаються з Середніх значень, зрілі стартапи
| **Мультипакунок для Monorepo** Бібліотеки, спільні кодові bases} Середньовіччя команди, OSS project ♪

### Що працює там

**Запуски і малі команди**: Почніть з використання заснованих на мітках або заснованих на гілках функцій. Не заповнюйте це поле просто - ви завжди зможете додати складність пізніше. Розвиток, заснований на Trunk, зі прапорцями функціональних можливостей є популярним на шкалі, але переповнений для малих команд.

**Підприємство**: Зазвичай, GitFlow або подібні до GitFlow для підтримки, аудиту слідів і керування запуском. Для забезпечення безпеки ланцюгів дедалі необхідні різноманітні середовища (dev, QA, storeing, prod). Арифметичні свідчення потрібні дедалі частіше.

**Розробники Solo**: "На основі теґів ідеальний, натискайте на мітку, активація відбувається." Без церемонії, без над головою.

**Платформа/ Ліберальні команди**: Потрібні монорепо стратегії з незалежними версіями для кожного пакунка. Семантична версія є вирішальною для споживача знизу.

## Деляція з мітками

Найпростіша і надійна стратегія: різні префікси міток ведуть до різних середовищ або спричиняють різні дії.

### Ціль середовища

```yaml
on:
  push:
    tags:
      - 'release-*'  # Production
      - 'local-*'    # Dev environment
```

```yaml
- 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
```

**Чому це працює**: Проста розумова модель, явне представлення, легке повернення з часовими мітками.

```bash
# 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
```

### Багатошарова версія

Для монорепоса з декількома пакунками, які можна опублікувати, скористайтеся префіксами теґів, щоб визначити, який пакунок слід випускати:

```yaml
# 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
```

Видобути версію і використовувати її протягом:

```yaml
- 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 }}
```

Для автоматичного версії, [МінВерCity in Massachusetts USA](https://github.com/adamralph/minver) Обчислює версії міток Git:

```xml
<PackageReference Include="MinVer" Version="6.0.0" PrivateAssets="all" />
<PropertyGroup>
  <MinVerTagPrefix>umamiv</MinVerTagPrefix>
</PropertyGroup>
```

## Внески з branch

Зменшувати код автоматично, якщо він потрапляє у певні гілки. Спільне використання у стартапі і командах швидкого створення коду.

```yaml
on:
  push:
    branches: [main]      # → Production
    # branches: [develop] # → Staging
```

**Pros**: Без ручного кроку, відкриття під час об' єднання
**Консептиди**: Можлива випадковість, менш детальна історія

Я використовую гібридний підхід - будую під час натискання гілки (перевірка CI), але оприлюднюю лише для міток:

```yaml
on:
  push:
    tags: ['scheduler-*']
    branches: [main, local]

jobs:
  build:
    # Always build
  publish:
    if: startsWith(github.ref, 'refs/tags/')  # Only publish on tags
```

## Автообстеження з " Вартовою баштою "

Для самоутверджених впровадження, [Вартова Башта](https://containrrr.dev/watchtower/) автоматичне перетягування нових зображень:

```yaml
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
```

**Потік в' язкості**: Штовхання теґу → Діла будує → Штовхнути до реєстру → Перезапускає контейнер. Всього часу: ~5 хвилин.

## Якість воріт

Швидка дія є марною, якщо ви розробляєте вади. Кожен робочий процес повинен містити ворота:

```yaml
- name: Run tests
  run: dotnet test --configuration Release

- name: Build
  run: dotnet build --configuration Release

# Tests or build fail → workflow stops → no publish
```

Для пакунків з декількома блоками збирання всіх цілей:

```yaml
- run: dotnet build -c Release --framework net8.0
- run: dotnet build -c Release --framework net9.0
```

## Без пароля публікування за допомогою OIDC

Сучасний підхід - немає таємниць для обертання, немає ключів для витікання:

```yaml
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 обмінює свій код OIDC на ключ програмного інтерфейсу NuGet. Щоб увімкнути цей параметр, налаштуйте довіру до NuGet.org.

## Доставка кайданів безпеки

[Артефактові свідчення](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations) Докажи, что твои артефакты были построены в институции, без вмешательства.

```yaml
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
```

Перевірка споживачів за допомогою: `gh attestation verify oci://index.docker.io/myuser/myapp:latest --owner myuser`

Досягнення [SLSA Рівень 2](https://slsa.dev/spec/v1.0/levels). Для рівня 3 використовуйте [Перезмінні робочі потоки](https://docs.github.com/en/actions/sharing-automations/reusing-workflows).

## Перегляд середовищ

Командам потрібні заповнювачі для попереднього перегляду змін перед об' єднанням.

**Індустріальний підхід** - Заснований на гілках об' єкти попереднього перегляду:

```yaml
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.
```

**Підхід до запуску/ соло** - Тунель вашої локальної машини:

```bash
# Cloudflare Tunnel (free)
cloudflared tunnel run --url http://localhost:5000 my-preview
# → https://my-preview.cfargotunnel.com
```

Або скористатися [Wireguard](https://www.wireguard.com/) VPN для внутрішнього доступу команди до вашого комп' ютера dev.

## Практичні поради

**Очищення міток**: Мітки назавжди приклеюються до мене.

```bash
git tag -d old-test-tag                      # Delete local
git push origin :refs/tags/old-test-tag      # Delete remote
```

**Конгреси**. Будьте послідовними.

- `release-YYYY.MM.DD` для виробництва
- `local-feature-name` для dev
- `packagev1.2.3` для бібліотек

**Таємниці**: Зберігати у [Секрети GitHub](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions)Обов' язкові секрети:

- `DOCKER_HUB_ACCESS_TOKEN`
- `NUGET_API_KEY` (або використовувати OIDC)
- `NPM_TOKEN`

**Розробка Monorepo**: Використовувати посилання на проект під час розробки, перемикатися на посилання на пакунки для перевірки реалізації:

```xml
<ProjectReference Include="..\MyLib\MyLib.csproj" />
<!-- <PackageReference Include="MyLib" Version="1.0.0" /> -->
```

## Переїзд до Kubernetes

Ті самі принципи, різні інструменти:

♪ Docle Compose} Kubernetes}
|----------------|------------|
♪ " Вартова башта " ♪ [ArgoCD](https://argo-cd.readthedocs.io/) / [Потік](https://fluxcd.io/docs/) |
cop-compose.yml}Істореси}
 Перезапустити ♪ 
 Перескочка ♪ GitOps drop back ♪

## Зведення

1. **Почати з простого**: Обкладинка, заснована на мітках, покриває більшість потреб
2. **За потреби додавати складність**: Заснований на гілках, багатовідсотковий, свідоцтва
3. **Автоматальна якісні ворота**: Перед опублікуванням потрібно пройти випробування
4. **Увімкнути зворотне повернення**: Часові мітки або журнал GitOps
5. **Забезпечити ваш трубопровод**: OIDC за секрети, свідчення для підтвердження
6. **Відповідність контексту**: Solo dev ▸ Старт - spell

Робочі потоки, показані тут, виконуються у цьому сховищі - check `.github/workflows/` для повномасштабних реалізацій.

**Запам' ятати**: Швидка, надійна трансляція - основа гнучкого розвитку.