Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/job-release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ on:
workflow_call:

outputs:

release-created:
description: Has a new release been created ?
value: ${{ jobs.prepare.outputs.releases-created && !contains(jobs.prepare.outputs.tag-name, 'rc') }}
Expand Down Expand Up @@ -57,7 +56,7 @@ jobs:
# This job handles (thus the `prepare` name) a prerelease/release MR,
# and provides the necessary outputs for the two subsequent jobs.
# It will either:
# - Upsert a prerelease MR after a commit has been added to the target branch (namely, `main`)
# - Upsert a prerelease MR after a commit has been added to the target branch (`releases`)
# - Create a prerelease (`X.Y.Z-rc`, `X.Y.Z-rc.1`, `X.Y.Z-rc.2`, etc.), if this workflow has been triggered by the related MR merge
# - Create a release (`X.Y.Z`), if this workflow has been triggered by the related MR merge
# - In both cases "Create" means:
Expand All @@ -81,6 +80,7 @@ jobs:
with:
config-file: ".github/prerelease-please-config.json"
manifest-file: ".github/prerelease-please-manifest.json"
target-branch: releases

# This job only runs when a prerelease has just been created and thus,
# will create/updade a subsequent "stable" release MR with the changelog incorporating the prereleases
Expand All @@ -99,6 +99,7 @@ jobs:
with:
config-file: .github/release-please-config.json
manifest-file: .github/release-please-manifest.json
target-branch: releases
token: ${{ secrets.GITHUB_TOKEN }}

# This job only runs when a release has just been created and thus,
Expand Down
71 changes: 7 additions & 64 deletions .github/workflows/workflow-handle-main.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
name: Handle next prerelease or release
name: Build and deploy latest from main

permissions:
# Needed for release job
issues: write
contents: write
pull-requests: write
# Needed for build job
contents: read
packages: write

on:
Expand All @@ -17,7 +13,6 @@ env:
REGISTRY: ghcr.io
NAMESPACE: "${{ github.repository }}"
BUILD_AMD64: true
BUILD_ARM64: true
USE_QEMU: false
NODE_VERSION: 26.7.0

Expand All @@ -28,78 +23,26 @@ jobs:
REGISTRY: ${{ env.REGISTRY }}
NAMESPACE: ${{ env.NAMESPACE }}
BUILD_AMD64: ${{ env.BUILD_AMD64 }}
BUILD_ARM64: ${{ env.BUILD_ARM64 }}
USE_QEMU: ${{ env.USE_QEMU }}
NODE_VERSION: ${{ env.NODE_VERSION }}
steps:
- name: Exposing env vars
run: echo "Exposing env vars"

release:
uses: ./.github/workflows/job-release-please.yml

build-amd64:
uses: ./.github/workflows/job-build.yml
# We build:
# - Whenever we push a commit on `main` branch, for CI purposes (we automatically push the build on our `cpin-hp` env)
# - Whenever we issue a new release, prerelease (both done on `main`)
if: ${{ github.ref == format('refs/heads/{0}', 'main') }}
needs:
- expose-vars
- release
with:
REGISTRY: ${{ needs.expose-vars.outputs.REGISTRY }}
NAMESPACE: ${{ needs.expose-vars.outputs.NAMESPACE }}
RELEASE_CREATED: ${{ needs.release.outputs.release-created == 'true' }}
TAG: ${{ needs.release.outputs.tag-name }}
MAJOR_TAG: ${{ needs.release.outputs.major-tag }}
MINOR_TAG: ${{ needs.release.outputs.minor-tag }}
PATCH_TAG: ${{ needs.release.outputs.patch-tag }}
RELEASE_CREATED: false
TAG: ''
MAJOR_TAG: ''
MINOR_TAG: ''
PATCH_TAG: ''
BUILD_AMD64: ${{ needs.expose-vars.outputs.BUILD_AMD64 == 'true' }}
BUILD_ARM64: false
USE_QEMU: ${{ needs.expose-vars.outputs.USE_QEMU == 'true' }}
secrets:
ARGOCD_TOKEN: ${{ secrets.ARGOCD_TOKEN }}

build-arm64:
uses: ./.github/workflows/job-build.yml
if: ${{ needs.release.outputs.release-created == 'true' || needs.release.outputs.prerelease-created == 'true' }}
needs:
- expose-vars
- release
with:
REGISTRY: ${{ needs.expose-vars.outputs.REGISTRY }}
NAMESPACE: ${{ needs.expose-vars.outputs.NAMESPACE }}
RELEASE_CREATED: ${{ needs.release.outputs.release-created == 'true' }}
TAG: ${{ needs.release.outputs.tag-name }}
MAJOR_TAG: ${{ needs.release.outputs.major-tag }}
MINOR_TAG: ${{ needs.release.outputs.minor-tag }}
PATCH_TAG: ${{ needs.release.outputs.patch-tag }}
BUILD_AMD64: false
BUILD_ARM64: ${{ needs.expose-vars.outputs.BUILD_ARM64 == 'true' }}
USE_QEMU: ${{ needs.expose-vars.outputs.USE_QEMU == 'true' }}
secrets:
ARGOCD_TOKEN: ${{ secrets.ARGOCD_TOKEN }}

update-chart:
runs-on: ubuntu-latest
if: ${{ needs.release.outputs.tag-name != '' }}
needs:
- expose-vars
- release
- build-amd64
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: helm-charts

- name: Trigger helm-charts update
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
gh workflow --repo cloud-pi-native/helm-charts run update-chart.yaml -f APP_VERSION=${{ needs.release.outputs.tag-name }} -f CHART_NAME=dso-console
100 changes: 100 additions & 0 deletions .github/workflows/workflow-handle-releases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Handle next prerelease or release

permissions:
issues: write
contents: write
pull-requests: write
packages: write

on:
push:
branches:
- releases

env:
REGISTRY: ghcr.io
NAMESPACE: "${{ github.repository }}"
BUILD_AMD64: true
BUILD_ARM64: true
USE_QEMU: false
NODE_VERSION: 26.7.0

jobs:
expose-vars:
runs-on: ubuntu-latest
outputs:
REGISTRY: ${{ env.REGISTRY }}
NAMESPACE: ${{ env.NAMESPACE }}
BUILD_AMD64: ${{ env.BUILD_AMD64 }}
BUILD_ARM64: ${{ env.BUILD_ARM64 }}
USE_QEMU: ${{ env.USE_QEMU }}
NODE_VERSION: ${{ env.NODE_VERSION }}
steps:
- name: Exposing env vars
run: echo "Exposing env vars"

release:
uses: ./.github/workflows/job-release-please.yml

build-amd64:
uses: ./.github/workflows/job-build.yml
if: ${{ needs.release.outputs.release-created == 'true' || needs.release.outputs.prerelease-created == 'true' }}
needs:
- expose-vars
- release
with:
REGISTRY: ${{ needs.expose-vars.outputs.REGISTRY }}
NAMESPACE: ${{ needs.expose-vars.outputs.NAMESPACE }}
RELEASE_CREATED: ${{ needs.release.outputs.release-created == 'true' }}
TAG: ${{ needs.release.outputs.tag-name }}
MAJOR_TAG: ${{ needs.release.outputs.major-tag }}
MINOR_TAG: ${{ needs.release.outputs.minor-tag }}
PATCH_TAG: ${{ needs.release.outputs.patch-tag }}
BUILD_AMD64: ${{ needs.expose-vars.outputs.BUILD_AMD64 == 'true' }}
BUILD_ARM64: false
USE_QEMU: ${{ needs.expose-vars.outputs.USE_QEMU == 'true' }}
secrets:
ARGOCD_TOKEN: ${{ secrets.ARGOCD_TOKEN }}

build-arm64:
uses: ./.github/workflows/job-build.yml
if: ${{ needs.release.outputs.release-created == 'true' || needs.release.outputs.prerelease-created == 'true' }}
needs:
- expose-vars
- release
with:
REGISTRY: ${{ needs.expose-vars.outputs.REGISTRY }}
NAMESPACE: ${{ needs.expose-vars.outputs.NAMESPACE }}
RELEASE_CREATED: ${{ needs.release.outputs.release-created == 'true' }}
TAG: ${{ needs.release.outputs.tag-name }}
MAJOR_TAG: ${{ needs.release.outputs.major-tag }}
MINOR_TAG: ${{ needs.release.outputs.minor-tag }}
PATCH_TAG: ${{ needs.release.outputs.patch-tag }}
BUILD_AMD64: false
BUILD_ARM64: ${{ needs.expose-vars.outputs.BUILD_ARM64 == 'true' }}
USE_QEMU: ${{ needs.expose-vars.outputs.USE_QEMU == 'true' }}
secrets:
ARGOCD_TOKEN: ${{ secrets.ARGOCD_TOKEN }}

update-chart:
runs-on: ubuntu-latest
if: ${{ needs.release.outputs.tag-name != '' }}
needs:
- expose-vars
- release
- build-amd64
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0
with:
app-id: ${{ secrets.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: helm-charts

- name: Trigger helm-charts update
env:
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
run: |
gh workflow --repo cloud-pi-native/helm-charts run update-chart.yaml -f APP_VERSION=${{ needs.release.outputs.tag-name }} -f CHART_NAME=dso-console
98 changes: 25 additions & 73 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Ce document décrit comment est géré le versionnement de `console`, c'est-à-d

Afin d'éviter une confusion entre les correctifs d'urgence ("hotfixes") — historiquement des versions `PATCH` rétroportées sur `main` — et les versions régulières produites par des commits `fix:`, les versions stables adoptent le protocole suivant :

- Les versions régulières sur `main` sont par défaut des `MINOR` (et très rarement des `MAJOR`).
- Les versions régulières sur `releases` sont par défaut des `MINOR` (et très rarement des `MAJOR`).
- Une préversion utilise la **prochaine** version stable visée, suffixée par `-rc`, puis `-rc.N` pour les candidates suivantes. Par exemple:
- Si la dernière version publiée est la `9.24.5`, la préversion (RC) suivante sera la `9.25.0-rc`
- Si la dernière version publiée est la `9.32.0-rc2`, la préversion suivante sera la `9.32.0-rc3`
Expand All @@ -27,90 +27,42 @@ La structure de versionnement stable de `console` est donc :
Les sections suivantes vont expliciter ce schéma:

```mermaid
gitGraph
branch release-please-main
commit id:" "

%% Initial state: latest tag on main = v1.2.5
checkout main
commit id: "Bump v1.2.5" tag: "v1.2.5"

%% Some commits are added to main
commit id: "feat: something"

%% Job create-or-update-release triggers release-please
%% which will upsert the next release MR, which will be a prerelease
checkout release-please-main
merge main
commit id: "Bump v1.3.0-rc"

%% Upon merging the release-please MR
%% The new tag is created
checkout main
merge release-please-main tag: "v1.3.0-rc"
%% and the release-please MR for the next stable release is created
checkout release-please-main
merge main
commit id: "Bump v1.3.0"

%% IF new commits are added BEFORE merging the release-please MR,
%% a new prerelease MR will replace the stable release MR
checkout main
commit id: "fix: something"
checkout release-please-main
merge main
commit id: "Bump v1.3.0-rc1"

%% Upon merging the release-please MR
%% The new tag is created
checkout main
merge release-please-main tag: "v1.3.0-rc1"
%% and the release-please MR for the next stable release is created
checkout release-please-main
merge main
commit id: "Bump v1.3.0 (updated)"

%% IF the stable release MR is merged into main
checkout main
merge release-please-main tag: "v1.3.0"

%% New commits are then pushed to main
%% and the cycle starts anew
commit id: "chore: something"

%% Job create-or-update-release triggers release-please
%% which will upsert the next release MR, which will be a prerelease
checkout release-please-main
merge main
commit id: "Bump v1.3.1-rc"
flowchart LR
M0["main: version stable N"] --> M1["main: nouvelles MRs fusionnées; build et déploiement latest"]
M0 --> R0["releases créée depuis le périmètre retenu sur main"]
M1 -. "correctif retenu : cherry-pick" .-> R1["releases: commits de qualification"]
R0 --> RP["Release Please cible releases"]
R1 --> RP
RP --> RC["Fusion de la PR RC sur releases; tag et build"]
RC --> ST["PR stable sur releases; fusion, tag et build"]
ST --> BACK["Après la stable : reporter les commits de version nécessaires sur main"]
BACK --> NEXT["Recréer releases depuis main pour le cycle suivant"]
```

## Versionnement de Console

Le flux de travail [`Handle next prerelease or release`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/workflow-handle-main.yml) est déclenché à chaque nouveau commit sur `main`. Il utilise le job réutilisable [`Next Prerelease and Release`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/job-release-please.yml) et notamment la GitHub Action [release-please-action](https://github.com/googleapis/release-please-action).
Le flux [`Build and deploy latest from main`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/workflow-handle-main.yml) est déclenché à chaque push sur `main`. Il construit la version d'intégration et déploie `latest`; il ne déclenche pas Release Please.

Le flux [`Handle next prerelease or release`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/workflow-handle-releases.yml) est déclenché à chaque push sur `releases`. Il appelle le job réutilisable [`Next Prerelease and Release`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/job-release-please.yml), avec `releases` comme branche cible pour les PR RC et stable. Les tags RC et stables déclenchent les builds d'artefacts et la mise à jour du chart. Le job de déploiement `latest` reste réservé aux événements de `main`.

Le flux de travail [`Handle next hotfix`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/workflow-handle-hotfix.yml) est déclenché à chaque nouveau commit sur une branche `hotfix/*`. Il utilise le job réutilisable [`Next Hotfix`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/job-release-please-hotfixes.yml).
Le flux [`Handle next hotfix`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/workflow-handle-hotfix.yml) est déclenché à chaque nouveau commit sur une branche `hotfix/*`. Il utilise le job réutilisable [`Next Hotfix`](https://github.com/cloud-pi-native/console/blob/main/.github/workflows/job-release-please-hotfixes.yml).

Trois configurations isolent les états de version :

- [`.github/prerelease-please-config.json`](./.github/prerelease-please-config.json) et son [manifeste](./.github/prerelease-please-manifest.json) gèrent les préversions (ou "Release Candidates", usuellement dénotées "RC") ;
- [`.github/release-please-config.json`](./.github/release-please-config.json) et son [manifeste](./.github/release-please-manifest.json) gèrent les versions "stables". La version stable met aussi à jour le manifeste de préversion afin de réinitialiser le cycle suivant depuis cette version (si on était à la `-rc14`, on réinitialise à `-rc` pour la prochaine version) ;
- [`.github/prerelease-please-config.json`](./.github/prerelease-please-config.json) et son [manifeste](./.github/prerelease-please-manifest.json) gèrent les préversions (ou "Release Candidates", usuellement dénotées "RC") sur `releases` ;
- [`.github/release-please-config.json`](./.github/release-please-config.json) et son [manifeste](./.github/release-please-manifest.json) gèrent les versions stables sur `releases`. La version stable met aussi à jour le manifeste de préversion afin de réinitialiser le cycle suivant depuis cette version (si on était à la `-rc14`, on réinitialise à `-rc` pour la prochaine version) ;
- [`.github/hotfix-release-please-config.json`](./.github/hotfix-release-please-config.json) et le manifeste de version stable gèrent les correctifs d'urgence. Cette configuration n'écrit jamais dans le manifeste de préversion.

À chaque exécution, le job `prepare` finalise d'abord toute requête de fusion de version déjà fusionnée, puis crée ou met à jour la prochaine requête de fusion.
Plus concrètement, le cycle est le suivant :
À chaque push sur `releases`, le job `prepare` finalise d'abord toute PR de version déjà fusionnée, puis crée ou met à jour la prochaine PR Release Please. Le cycle manuel est le suivant :

1. Les commits classiques (`feat`, `chore`, etc.) sur `main` déclenchent les workflows GitHub qui vont créer/mettre à jour une MR de préversion.
2. La fusion de cette MR dans `main` crée effectivement la préversion:
a. Création du tag git `vX.Y.Z-rc`. Les RC suivantes de la même version sont taguées `vX.Y.Z-rc.N`, où `N` vaut `1`, puis `2`, etc.
b. Création des images OCI/docker poussées en tant que "packages" dans l'organisation GitHub `cloud-pi-native`
c. Création de la Release GitHub, avec cependant une étiquette `Pre-release` pour indiquer que ce n'est pas une version "stable". Ce n'est, par exemple, pas la version qui est affichée sur la page de garde du dépôt
d. Création de la MR côté `helm-chart` qui va faire un bump mineur du chart `dso-console` avec comme `appVersion` la version RC nouvellement créée (il faudra alors fusionner cette MR pour avoir un chart à jour)
3. Après la création de la préversion, vu que son commit de "bump" de version a été poussé sur `main`, les workflows sont à nouveaux déclenchés et une MR de version stable `vX.Y.Z` est créée.
4. La fusion de cette MR crée la Release GitHub stable `vX.Y.Z`
5. Tout nouveau commit classique poussé sur `main` déclenchera la création de la prochaine MR de préversion (retour à l'étape 1)
1. Au début d'une qualification, créer `releases` depuis le commit de `main` qui définit le périmètre de la version et pousser cette branche. Pour la bascule du cycle existant, fermer sans la fusionner l'ancienne PR Release Please qui cible `main`, puis créer `releases` depuis l'état de `main` contenant la dernière RC publiée. Release Please crée alors la PR de version sur `releases`.
2. Fusionner les MRs fonctionnelles sur `main` comme d'habitude. Elles continuent à alimenter le build et le déploiement `latest`, sans créer de RC.
3. Pour inclure une correction dans la version en qualification, cherry-picker son commit de `main` sur `releases`. Release Please crée ou met à jour la PR RC ciblant `releases`.
4. Fusionner la PR RC sur `releases` pour créer le tag `vX.Y.Z-rc` ou `vX.Y.Z-rc.N`, la Release GitHub « Pre-release » et les builds d'artefacts correspondants. Le flux existant déclenche également la mise à jour du chart Helm.
5. Après une RC, Release Please crée ou met à jour la PR de version stable `vX.Y.Z`, toujours ciblant `releases`. La fusion de cette PR crée le tag et la Release GitHub stables, les builds d'artefacts et les tags partiels `vX` et `vX.Y`.
6. Après la stable, reporter sur `main` uniquement les commits de version/release nécessaires qui ne s'y trouvent pas déjà. Ne pas fusionner l'ensemble de `releases`, qui contient des cherry-picks de commits déjà présents sur `main`. Supprimer ensuite `releases` et la recréer depuis `main` au début de la qualification suivante.

**⚠️NOTE⚠️**: Si jamais, après l'étape `3` (création de la MR pour la version stable) des commits "classiques" sont poussés sur `main` alors **la MR de la version stable sera automatiquement "convertie" en MR de préversion**. Dit autrement: **On ne peut créer une version "stable" qu'à partir d'une préversion**. Tout commit en plus empêche d'avoir une version stable, il faut forcément qu'il y ait ZERO commit après une préversion pour avoir une MR de version stable.
Les commits qui ne sont pas cherry-pickés sur `releases` restent hors du périmètre de la version en qualification. Le cycle de Release Please régulier ne démarre pas depuis `main`.

## Notes de version

Expand Down
Loading