From 7bf395afabea996f43dfea9868dc1e7633e76d25 Mon Sep 17 00:00:00 2001 From: Laurent Trinques Date: Thu, 14 May 2026 09:53:29 +0200 Subject: [PATCH] =?UTF-8?q?Every=20Monday=20at=202=20am=20(UTC)=20(cron)?= =?UTF-8?q?=20or=20manually=20=20=20=20=20=20=20=20=20=E2=86=93=20=20=20wi?= =?UTF-8?q?ndows-build.yml=20=20=20=E2=94=9C=E2=94=80=E2=94=80=20build-win?= =?UTF-8?q?dows=20=20=E2=86=92=20=20generates=20an=20exe=20file=20+=20zip?= =?UTF-8?q?=20+=20portable=20artefact=20=20=20=E2=94=94=E2=94=80=E2=94=80?= =?UTF-8?q?=20deploy-pages=20=20=20=E2=86=92=20=20clears=20old=20files,=20?= =?UTF-8?q?uploads=20the=20exe=20file=20+=20zip=20to=20the=20=E2=80=98rele?= =?UTF-8?q?ase=20nightly=E2=80=99=20repository=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=E2=86=93=20(workflow=5Frun:=20completed=20+=20successful)=20?= =?UTF-8?q?=20=20windows-msi.yml=20=20=20=E2=94=9C=E2=94=80=E2=94=80=20upl?= =?UTF-8?q?oads=20the=20portable=20artefact=20=20=20=E2=94=9C=E2=94=80?= =?UTF-8?q?=E2=94=80=20builds=20the=20MSI=20with=20WiX=20v7=20=20=20?= =?UTF-8?q?=E2=94=9C=E2=94=80=E2=94=80=20deletes=20the=20old=20.msi,=20upl?= =?UTF-8?q?oads=20the=20MSI=20to=20the=20nightly=20version=20=20=20?= =?UTF-8?q?=E2=94=94=E2=94=80=E2=94=80=20generates=20and=20deploys=20GitHu?= =?UTF-8?q?b=20Pages=20=20=E2=86=90=20the=203=20URLs=20are=20known=20here?= =?UTF-8?q?=20The=20GitHub=20Pages=20page=20is=20no=20longer=20generated?= =?UTF-8?q?=20by=20windows-build.yml=20but=20by=20windows-msi.yml=20once?= =?UTF-8?q?=20the=20MSI=20is=20in=20the=20release?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/windows-build.yml | 62 +++++++------------- .github/workflows/windows-msi.yml | 88 ++++++++++++++++++++++++++--- 2 files changed, 99 insertions(+), 51 deletions(-) diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index e5c77e4db..a42110b27 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -1,11 +1,9 @@ name: Windows Build on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - workflow_dispatch: + schedule: + - cron: '0 2 * * 1' # Every Monday at 2:00 UTC + workflow_dispatch: # Manual trigger available at any time concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -366,8 +364,6 @@ jobs: if: github.event_name != 'pull_request' permissions: contents: write - pages: write - id-token: write steps: - name: Checkout master (for build-aux scripts) @@ -391,6 +387,20 @@ jobs: path: downloaded/portable/ merge-multiple: true + - name: Delete old nightly assets (.exe and .zip) + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + run: | + # Fetch existing .exe and .zip asset names and delete them + gh release view nightly --repo "$REPO" --json assets \ + --jq '.assets[] | select(.name | test("\\.(exe|zip)$")) | .name' \ + | while read -r name; do + echo "Deleting old asset: $name" + gh release delete-asset nightly "$name" --repo "$REPO" --yes + done + echo "Old .exe and .zip assets deleted." + - name: Update nightly release uses: softprops/action-gh-release@v2 with: @@ -414,39 +424,5 @@ jobs: downloaded/portable/*.zip token: ${{ secrets.GITHUB_TOKEN }} - - name: Generate download page (index.html) - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DATE: "placeholder" - run: | - DATE=$(date -u '+%Y-%m-%d %H:%M UTC') - SHORT="${{ github.sha }}" - SHORT="${SHORT:0:7}" - REPO="${{ github.repository }}" - RUN_URL="https://github.com/$REPO/actions/runs/${{ github.run_id }}" - EXE_NAME=$(ls downloaded/installer/*.exe | xargs -I{} basename {}) - INSTALLER_URL="https://github.com/$REPO/releases/download/nightly/$EXE_NAME" - ZIP_NAME=$(ls downloaded/portable/*.zip | xargs -I{} basename {}) - PORTABLE_URL="https://github.com/$REPO/releases/download/nightly/$ZIP_NAME" - MSI_NAME=$(gh release view nightly --json assets --jq '.assets[].name' 2>/dev/null \ - | grep '\.msi$' | head -1 || echo "") - MSI_URL="" - [ -n "$MSI_NAME" ] && MSI_URL="https://github.com/$REPO/releases/download/nightly/$MSI_NAME" - DATE=$(date -u '+%Y-%m-%d %H:%M UTC') - export DATE SHORT REPO SHA="${{ github.sha }}" RUN_URL - export RUN_NUMBER="${{ github.run_number }}" - export INSTALLER_URL PORTABLE_URL MSI_URL - # Write the page generator script to /tmp (build-aux/ not available - # in deploy-pages job which only checks out gh-pages branch) - python3 source/build-aux/generate-page.py - - - name: Add .nojekyll to disable Jekyll processing - run: touch gh-pages/.nojekyll - - - name: Upload GitHub Pages artifact - uses: actions/upload-pages-artifact@v3 - with: - path: gh-pages/ - - - name: Deploy to GitHub Pages - uses: actions/deploy-pages@v4 + # GitHub Pages is generated and deployed by windows-msi.yml + # after the MSI upload, so that all 3 URLs (exe, zip, msi) are known. diff --git a/.github/workflows/windows-msi.yml b/.github/workflows/windows-msi.yml index a7a4b4b48..104789085 100644 --- a/.github/workflows/windows-msi.yml +++ b/.github/workflows/windows-msi.yml @@ -1,12 +1,12 @@ name: Windows MSI (WiX v7) on: - # Déclenché automatiquement après un build Windows réussi sur master + # Triggered automatically after a successful Windows build on master workflow_run: workflows: ["Windows Build"] types: [completed] branches: [master] - # Toujours possible de lancer manuellement (ex: pour un run_id spécifique) + # Manual trigger still available (e.g. for a specific run_id) workflow_dispatch: inputs: run_id: @@ -18,10 +18,14 @@ jobs: build-msi: name: Build MSI with WiX v7 runs-on: windows-latest - # Ne tourne que si le workflow Windows Build a réussi (ou si c'est manuel) + # Only runs if Windows Build succeeded (or triggered manually) if: > github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' + permissions: + contents: write + pages: write + id-token: write steps: # ---------------------------------------------------------------- @@ -42,8 +46,8 @@ jobs: with: name: qelectrotech-windows-portable path: artifact\files - # workflow_run => utilise l'ID du run déclencheur - # workflow_dispatch => utilise l'input run_id si fourni, sinon le run courant + # workflow_run => use the triggering run's ID + # workflow_dispatch => use input run_id if provided, otherwise current run run-id: ${{ github.event.workflow_run.id || github.event.inputs.run_id || github.run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} repository: ${{ github.repository }} @@ -259,10 +263,22 @@ jobs: if-no-files-found: error # ---------------------------------------------------------------- - # 11. Upload MSI to nightly release - # The nightly release is created/updated by windows-build.yml. - # The MSI is added here so the GitHub Pages can link to it. + # 11. Delete old .msi asset then upload new MSI to nightly release # ---------------------------------------------------------------- + - name: Delete old nightly .msi asset + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + run: | + gh release view nightly --repo "$REPO" --json assets \ + --jq '.assets[] | select(.name | test("\\.msi$")) | .name' \ + | while read -r name; do + echo "Deleting old asset: $name" + gh release delete-asset nightly "$name" --repo "$REPO" --yes + done + echo "Old .msi assets deleted." + shell: bash + - name: Upload MSI to nightly release uses: softprops/action-gh-release@v2 with: @@ -289,3 +305,59 @@ jobs: } else { Write-Host "MSI : FAILED ✗" } + + # ---------------------------------------------------------------- + # 13. Generate and deploy the GitHub Pages download page + # Toutes les URLs sont connues ici (exe, zip, msi). + # ---------------------------------------------------------------- + - name: Checkout (for generate-page.py) + uses: actions/checkout@v4 + with: + ref: master + path: source + sparse-checkout: build-aux/generate-page.py + sparse-checkout-cone-mode: false + + - name: Generate download page (index.html) + shell: bash + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + REPO="${{ github.repository }}" + + # Fetch asset names from the nightly release (source of truth) + ASSETS=$(gh release view nightly --repo "$REPO" --json assets --jq '.assets[].name') + + EXE_NAME=$(echo "$ASSETS" | grep '\.exe$' | head -1) + ZIP_NAME=$(echo "$ASSETS" | grep '\.zip$' | head -1) + MSI_NAME=$(echo "$ASSETS" | grep '\.msi$' | head -1 || echo "") + + BASE="https://github.com/$REPO/releases/download/nightly" + INSTALLER_URL="$BASE/$EXE_NAME" + PORTABLE_URL="$BASE/$ZIP_NAME" + MSI_URL="" + [ -n "$MSI_NAME" ] && MSI_URL="$BASE/$MSI_NAME" + + SHA="${{ github.event.workflow_run.head_sha || github.sha }}" + SHORT="${SHA:0:7}" + DATE=$(date -u '+%Y-%m-%d %H:%M UTC') + RUN_URL="https://github.com/$REPO/actions/runs/${{ github.run_id }}" + RUN_NUMBER="${{ github.run_number }}" + + export DATE SHORT REPO SHA RUN_URL RUN_NUMBER + export INSTALLER_URL PORTABLE_URL MSI_URL + + python3 source/build-aux/generate-page.py + + - name: Add .nojekyll + shell: bash + run: touch gh-pages/.nojekyll + + - name: Upload GitHub Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: gh-pages/ + + - name: Deploy to GitHub Pages + uses: actions/deploy-pages@v4