@@ -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,128 +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-
153- # ---------- Preprod path: create RC tag + pre-release ----------
154- - name : " Create/Push RC tag for preprod"
155- if : ${{ needs.metadata.outputs.environment == 'preprod' }}
156- id : rc_tag
157- shell : bash
158- run : |
159- set -euo pipefail
160- git fetch --tags
161-
162- # Helper: get latest final and latest RC (across all bases)
163- latest_final="$(git tag -l 'v[0-9]*.[0-9]*.[0-9]*' \
164- | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1 || true)"
165- latest_any_rc="$(git tag -l 'v[0-9]*.[0-9]*.[0-9]*-rc.*' \
166- | sort -V | tail -n1 || true)"
167-
168- # Determine the base version (vX.Y.Z) we will use for the next RC.
169- # If release_type=rc and we already have RCs, keep the SAME base as the latest RC.
170- # Otherwise, derive base from latest FINAL and bump per release_type.
171- if [[ "${{ inputs.release_type }}" == "rc" && -n "${latest_any_rc}" ]]; then
172- base="${latest_any_rc%-rc.*}" # strip '-rc.N' → vX.Y.Z
173- else
174- # Start from latest FINAL (or 0.0.0 if none)
175- if [[ -z "${latest_final}" ]]; then
176- base_major=0; base_minor=0; base_patch=0
177- else
178- IFS='.' read -r base_major base_minor base_patch <<< "${latest_final#v}"
179- fi
180-
181- case "${{ inputs.release_type }}" in
182- major) base_major=$((base_major+1)); base_minor=0; base_patch=0 ;;
183- minor) base_minor=$((base_minor+1)); base_patch=0 ;;
184- patch|rc|*) base_patch=$((base_patch+1)) ;; # 'rc' with no prior RCs → default to patch bump
185- esac
186-
187- base="v${base_major}.${base_minor}.${base_patch}"
188- fi
189-
190- # Compute next RC number for this base
191- last_rc_for_base="$(git tag -l "${base}-rc.*" | sort -V | tail -n1 || true)"
192- if [[ -z "${last_rc_for_base}" ]]; then
193- next_rc="${base}-rc.1"
194- else
195- n="${last_rc_for_base##*-rc.}"
196- next_rc="${base}-rc.$((n+1))"
197- fi
198-
199- # Tag current commit (whatever ref was checked out)
200- sha="$(git rev-parse HEAD)"
201- echo "Tagging ${sha} as ${next_rc}"
202- git tag -a "${next_rc}" "${sha}" -m "Release candidate ${next_rc}"
203- git push origin "${next_rc}"
204-
205- echo "rc=${next_rc}" >> "$GITHUB_OUTPUT"
206-
207- - name : " Create GitHub Pre-release (preprod)"
208- if : ${{ needs.metadata.outputs.environment == 'preprod' }}
209- uses : actions/create-release@v1
156+ - name : " Validate Feature Toggles"
210157 env :
211- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
212- with :
213- tag_name : ${{ steps.rc_tag.outputs.rc }}
214- release_name : " Pre-release ${{ steps.rc_tag.outputs.rc }}"
215- body : |
216- Auto pre-release created during preprod deployment.
217- draft : false
218- prerelease : true
219-
220- # ---------- Prod path: promote RC to final ----------
221- - name : " Validate input is an RC tag (prod)"
222- if : ${{ needs.metadata.outputs.environment == 'prod' }}
223- shell : bash
224- run : |
225- set -euo pipefail
226- ref="${{ needs.metadata.outputs.ref }}"
227- if [[ ! "$ref" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$ ]]; then
228- echo "ERROR: For prod, 'ref' must be an RC tag like v1.4.0-rc.2 (got: $ref)"
229- exit 1
230- fi
231- git fetch --tags --quiet
232- if ! git rev-parse -q --verify "refs/tags/$ref" >/dev/null; then
233- echo "ERROR: Tag '$ref' does not exist on origin."
234- exit 1
235- fi
236-
237- - name : " Create final tag from RC (prod)"
238- if : ${{ needs.metadata.outputs.environment == 'prod' }}
239- id : final_tag
240- shell : bash
158+ ENV : ${{ needs.metadata.outputs.environment }}
241159 run : |
242- set -euo pipefail
243- rc="${{ needs.metadata.outputs.ref }}"
244- final="${rc%-rc.*}" # strip '-rc.N'
245- sha=$(git rev-list -n 1 "$rc")
246-
247- if git rev-parse -q --verify "refs/tags/${final}" >/dev/null; then
248- echo "ERROR: Final tag ${final} already exists."
249- exit 1
250- fi
251-
252- echo "Promoting $rc ($sha) to final $final"
253- git tag -a "${final}" "${sha}" -m "Release ${final}"
254- git push origin "${final}"
255- echo "final=${final}" >> $GITHUB_OUTPUT
160+ pip install boto3
161+ python scripts/feature_toggle/validate_toggles.py
256162
257- - name : " Create GitHub Release (prod)"
258- if : ${{ needs.metadata.outputs.environment == 'prod' }}
259- uses : actions/create-release@v1
163+ - name : " Tag and Release"
164+ if : ${{ needs.metadata.outputs.environment == 'preprod' || needs.metadata.outputs.environment == 'prod' }}
260165 env :
166+ ENVIRONMENT : ${{ needs.metadata.outputs.environment }}
167+ REF : ${{ needs.metadata.outputs.ref }}
168+ INPUT_RELEASE_TYPE : ${{ inputs.release_type }}
261169 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
262- with :
263- tag_name : ${{ steps.final_tag.outputs.final }}
264- release_name : " Release ${{ steps.final_tag.outputs.final }}"
265- body : |
266- Auto-release created during production deployment.
267- draft : false
268- prerelease : false
170+ GITHUB_REPOSITORY : ${{ github.repository }}
171+ run : poetry run python scripts/workflow/tag_and_release.py
172+
269173
270174 regression-tests :
271175 name : " Regression Tests"
0 commit comments