@@ -89,10 +89,19 @@ jobs:
8989 with :
9090 terraform_version : ${{ needs.metadata.outputs.terraform_version }}
9191
92+ - name : " Install Poetry"
93+ run : |
94+ curl -sSL https://install.python-poetry.org | python3 -
95+ echo "$HOME/.local/bin" >> $GITHUB_PATH
96+
9297 - name : " Set up Python"
9398 uses : actions/setup-python@v5
9499 with :
95100 python-version : " 3.13"
101+ cache : ' poetry'
102+
103+ - name : " Install dependencies"
104+ run : poetry install
96105
97106 - name : " Checkout repository at ref"
98107 uses : actions/checkout@v5
@@ -144,135 +153,23 @@ jobs:
144153 echo "Running: make terraform env=$ENVIRONMENT workspace=$WORKSPACE stack=api-layer tf-command=apply"
145154 make terraform env=$ENVIRONMENT stack=api-layer tf-command=apply workspace=$WORKSPACE
146155
147- - name : " Set up git identity"
148- if : ${{ needs.metadata.outputs.environment == 'preprod' || needs.metadata.outputs.environment == 'prod' }}
149- run : |
150- git config user.name "github-actions"
151- git config user.email "[email protected] " 152-
153156 - name : " Validate Feature Toggles"
154157 env :
155158 ENV : ${{ needs.metadata.outputs.environment }}
156159 run : |
157160 pip install boto3
158161 python scripts/feature_toggle/validate_toggles.py
159162
160- # ---------- Preprod path: create RC tag + pre-release ----------
161- - name : " Create/Push RC tag for preprod"
162- if : ${{ needs.metadata.outputs.environment == 'preprod' }}
163- id : rc_tag
164- shell : bash
165- run : |
166- set -euo pipefail
167- git fetch --tags
168-
169- # Helper: get latest final and latest RC (across all bases)
170- latest_final="$(git tag -l 'v[0-9]*.[0-9]*.[0-9]*' \
171- | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1 || true)"
172- latest_any_rc="$(git tag -l 'v[0-9]*.[0-9]*.[0-9]*-rc.*' \
173- | sort -V | tail -n1 || true)"
174-
175- # Determine the base version (vX.Y.Z) we will use for the next RC.
176- # If release_type=rc and we already have RCs, keep the SAME base as the latest RC.
177- # Otherwise, derive base from latest FINAL and bump per release_type.
178- if [[ "${{ inputs.release_type }}" == "rc" && -n "${latest_any_rc}" ]]; then
179- base="${latest_any_rc%-rc.*}" # strip '-rc.N' → vX.Y.Z
180- else
181- # Start from latest FINAL (or 0.0.0 if none)
182- if [[ -z "${latest_final}" ]]; then
183- base_major=0; base_minor=0; base_patch=0
184- else
185- IFS='.' read -r base_major base_minor base_patch <<< "${latest_final#v}"
186- fi
187-
188- case "${{ inputs.release_type }}" in
189- major) base_major=$((base_major+1)); base_minor=0; base_patch=0 ;;
190- minor) base_minor=$((base_minor+1)); base_patch=0 ;;
191- patch|rc|*) base_patch=$((base_patch+1)) ;; # 'rc' with no prior RCs → default to patch bump
192- esac
193-
194- base="v${base_major}.${base_minor}.${base_patch}"
195- fi
196-
197- # Compute next RC number for this base
198- last_rc_for_base="$(git tag -l "${base}-rc.*" | sort -V | tail -n1 || true)"
199- if [[ -z "${last_rc_for_base}" ]]; then
200- next_rc="${base}-rc.1"
201- else
202- n="${last_rc_for_base##*-rc.}"
203- next_rc="${base}-rc.$((n+1))"
204- fi
205-
206- # Tag current commit (whatever ref was checked out)
207- sha="$(git rev-parse HEAD)"
208- echo "Tagging ${sha} as ${next_rc}"
209- git tag -a "${next_rc}" "${sha}" -m "Release candidate ${next_rc}"
210- git push origin "${next_rc}"
211-
212- echo "rc=${next_rc}" >> "$GITHUB_OUTPUT"
213-
214- - name : " Create GitHub Pre-release (preprod)"
215- if : ${{ needs.metadata.outputs.environment == 'preprod' }}
216- uses : actions/create-release@v1
163+ - name : " Tag and Release"
164+ if : ${{ needs.metadata.outputs.environment == 'preprod' || needs.metadata.outputs.environment == 'prod' }}
217165 env :
166+ ENVIRONMENT : ${{ needs.metadata.outputs.environment }}
167+ REF : ${{ needs.metadata.outputs.ref }}
168+ INPUT_RELEASE_TYPE : ${{ inputs.release_type }}
218169 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
219- with :
220- tag_name : ${{ steps.rc_tag.outputs.rc }}
221- release_name : " Pre-release ${{ steps.rc_tag.outputs.rc }}"
222- body : |
223- Auto pre-release created during preprod deployment.
224- draft : false
225- prerelease : true
226-
227- # ---------- Prod path: promote RC to final ----------
228- - name : " Validate input is an RC tag (prod)"
229- if : ${{ needs.metadata.outputs.environment == 'prod' }}
230- shell : bash
231- run : |
232- set -euo pipefail
233- ref="${{ needs.metadata.outputs.ref }}"
234- if [[ ! "$ref" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
235- echo "ERROR: For prod, 'ref' must be an RC tag like v1.4.0-rc.2 (got: $ref)"
236- exit 1
237- fi
238- git fetch --tags --quiet
239- if ! git rev-parse -q --verify "refs/tags/$ref" >/dev/null; then
240- echo "ERROR: Tag '$ref' does not exist on origin."
241- exit 1
242- fi
243-
244- - name : " Create final tag from RC (prod)"
245- if : ${{ needs.metadata.outputs.environment == 'prod' }}
246- id : final_tag
247- shell : bash
248- run : |
249- set -euo pipefail
250- rc="${{ needs.metadata.outputs.ref }}"
251- final="${rc%-rc.*}" # strip '-rc.N'
252- sha=$(git rev-list -n 1 "$rc")
253-
254- if git rev-parse -q --verify "refs/tags/${final}" >/dev/null; then
255- echo "ERROR: Final tag ${final} already exists."
256- exit 1
257- fi
170+ GITHUB_REPOSITORY : ${{ github.repository }}
171+ run : poetry run python scripts/workflow/tag_and_release.py
258172
259- echo "Promoting $rc ($sha) to final $final"
260- git tag -a "${final}" "${sha}" -m "Release ${final}"
261- git push origin "${final}"
262- echo "final=${final}" >> $GITHUB_OUTPUT
263-
264- - name : " Create GitHub Release (prod)"
265- if : ${{ needs.metadata.outputs.environment == 'prod' }}
266- uses : actions/create-release@v1
267- env :
268- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
269- with :
270- tag_name : ${{ steps.final_tag.outputs.final }}
271- release_name : " Release ${{ steps.final_tag.outputs.final }}"
272- body : |
273- Auto-release created during production deployment.
274- draft : false
275- prerelease : false
276173
277174 regression-tests :
278175 name : " Regression Tests"
0 commit comments