Modularize terrain orchestration and shared zone CLI #61
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release (build 3 OS) | |
| # Build des exécutables autonomes sur les 3 OS puis publication sur la release. | |
| # PyInstaller n'est pas un cross-compilateur : chaque binaire DOIT être produit | |
| # sur son OS/arch natif. Ce workflow le fait sur les runners GitHub. | |
| # | |
| # Déclenchement : | |
| # - push d'un tag v* (ex: git tag v1.3.0 && git push origin v1.3.0) | |
| # - manuel (workflow_dispatch) avec saisie du tag | |
| # | |
| # Assets produits (noms attendus par update_app.py) : | |
| # lidar2map-windows-x86_64.zip (dossier : lidar2map.exe + lidar2map_bundle.zip) | |
| # lidar2map-linux-x86_64.tar.gz (dossier : lidar2map + lidar2map_bundle.zip) | |
| # lidar2map-macos-arm64.zip (LIDAR2MAP.app zippé via ditto, Apple Silicon) | |
| # lidar2map-macos-x86_64.zip (idem, Mac Intel) | |
| # | |
| # L'exécution distante (rlidar2map_CLI / rlidar2map_GUI) est embarquée dans | |
| # ces mêmes bundles : plus d'archives séparées. Voir --remote-cli / | |
| # --remote-gui et tools/README_rlidar2map.md. | |
| # | |
| # Deux runners macOS : macos-latest est Apple Silicon depuis 2024, il ne peut | |
| # donc plus produire de binaire Intel. macos-15-intel est le dernier runner | |
| # x86_64 standard (gratuit sur repo public), annoncé jusqu'à août 2027. Après | |
| # cette date, il faudra soit abandonner l'asset Intel, soit builder sur une | |
| # machine Intel perso. | |
| # | |
| # NB : le build lidar2map est lourd (JRE + osmosis + Qt/QtWebEngine + deps géo) : | |
| # onedir ~1,2 Go, bundle ~450 Mo. Les setup_build_* téléchargent JRE+osmosis | |
| # (--telecharger-outils). Prévoir des jobs longs (timeout-minutes). | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Tag de la release (ex: v1.3.0)' | |
| required: true | |
| jobs: | |
| build: | |
| name: build ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 90 | |
| env: | |
| # GitHub n'autorise pas secrets.* directement dans un `if`; passage par | |
| # le contexte env pour rendre toute la chaîne Apple strictement optionnelle. | |
| MACOS_CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE_BASE64 }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [windows-latest, ubuntu-latest, macos-latest, macos-15-intel] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Setup Python 3.12 | |
| uses: actions/setup-python@v6 | |
| with: | |
| # 3.12.13 est source-only sur python.org ; setup-python sélectionne | |
| # ici une distribution 3.12 disponible pour chaque runner. | |
| python-version: "3.12" | |
| # Secrets optionnels pour une distribution sans alerte Gatekeeper : | |
| # MACOS_CERTIFICATE_BASE64 (.p12 encodé en base64) | |
| # MACOS_CERTIFICATE_PASSWORD, MACOS_KEYCHAIN_PASSWORD | |
| # MACOS_CODESIGN_IDENTITY (Developer ID Application: ...) | |
| # APPLE_ID, APPLE_TEAM_ID, APPLE_APP_PASSWORD | |
| # Sans eux, le build reste ad hoc mais sa signature finale est valide. | |
| - name: Configure Apple signing and notarization | |
| if: runner.os == 'macOS' && env.MACOS_CERTIFICATE_BASE64 != '' | |
| env: | |
| MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} | |
| MACOS_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} | |
| MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }} | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }} | |
| run: | | |
| set -euo pipefail | |
| CERTIFICATE_PATH="$RUNNER_TEMP/lidar2map-signing.p12" | |
| KEYCHAIN_PATH="$RUNNER_TEMP/lidar2map-build.keychain-db" | |
| printf '%s' "$MACOS_CERTIFICATE_BASE64" | base64 -D > "$CERTIFICATE_PATH" | |
| security create-keychain -p "$MACOS_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$MACOS_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security import "$CERTIFICATE_PATH" -P "$MACOS_CERTIFICATE_PASSWORD" \ | |
| -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" | |
| security list-keychain -d user -s "$KEYCHAIN_PATH" | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: \ | |
| -s -k "$MACOS_KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| xcrun notarytool store-credentials lidar2map-notary \ | |
| --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" \ | |
| --password "$APPLE_APP_PASSWORD" --keychain "$KEYCHAIN_PATH" | |
| echo "LIDAR2MAP_CODESIGN_IDENTITY=$MACOS_CODESIGN_IDENTITY" >> "$GITHUB_ENV" | |
| echo "LIDAR2MAP_NOTARY_PROFILE=lidar2map-notary" >> "$GITHUB_ENV" | |
| echo "LIDAR2MAP_NOTARY_KEYCHAIN=$KEYCHAIN_PATH" >> "$GITHUB_ENV" | |
| # ── Windows ────────────────────────────────────────────────────────── | |
| - name: Setup machine (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: .\setup_build_windows.ps1 | |
| - name: Build (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: .\lidar2map_win_build.ps1 | |
| - name: Package (Windows) | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: | | |
| $stage = "dist\lidar2map-windows-x86_64" | |
| New-Item -ItemType Directory -Force $stage | Out-Null | |
| Copy-Item dist\lidar2map.exe $stage\ | |
| Copy-Item dist\lidar2map_bundle.zip $stage\ | |
| Copy-Item lidar2map_icon.png $stage\ | |
| $zip = "dist\lidar2map-windows-x86_64.zip" | |
| Compress-Archive -Path $stage -DestinationPath $zip -Force | |
| (Get-FileHash $zip -Algorithm SHA256).Hash.ToLower() | | |
| Out-File "$zip.sha256" -Encoding ascii -NoNewline | |
| # ── Linux ──────────────────────────────────────────────────────────── | |
| - name: Setup machine (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| sudo apt-get update -qq | |
| sudo apt-get install -y zip | |
| bash setup_build_linux.sh | |
| - name: Build (Linux) | |
| if: runner.os == 'Linux' | |
| run: bash lidar2map_linux_build.sh | |
| - name: Package (Linux) | |
| if: runner.os == 'Linux' | |
| run: | | |
| mkdir -p dist/lidar2map-linux-x86_64 | |
| cp dist/lidar2map dist/lidar2map-linux-x86_64/ | |
| cp dist/lidar2map_bundle.zip dist/lidar2map-linux-x86_64/ | |
| cp lidar2map_icon.png dist/lidar2map-linux-x86_64/ | |
| tar czf dist/lidar2map-linux-x86_64.tar.gz -C dist lidar2map-linux-x86_64 | |
| sha256sum dist/lidar2map-linux-x86_64.tar.gz | awk '{print $1}' \ | |
| > dist/lidar2map-linux-x86_64.tar.gz.sha256 | |
| # ── macOS ──────────────────────────────────────────────────────────── | |
| - name: Setup machine (macOS) | |
| if: runner.os == 'macOS' | |
| run: bash setup_build_mac.sh | |
| - name: Build (macOS) | |
| if: runner.os == 'macOS' | |
| run: bash lidar2map_mac_build.sh | |
| - name: Package (macOS) | |
| if: runner.os == 'macOS' | |
| run: | | |
| set -euo pipefail | |
| # Le nom du zip porte l'archi du runner (arm64 ou x86_64) : on le | |
| # retrouve au glob plutôt que de le coder en dur. | |
| zip=$(ls dist/lidar2map-macos-*.zip) | |
| shasum -a 256 "$zip" | awk '{print $1}' > "$zip.sha256" | |
| # ── Upload artefact (asset + .sha256) ──────────────────────────────── | |
| - name: Upload artefact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| # matrix.os et non runner.os : les deux jobs macOS renverraient tous | |
| # deux "macOS", et upload-artifact@v4 refuse deux artefacts de même nom. | |
| name: asset-${{ matrix.os }} | |
| if-no-files-found: error | |
| path: | | |
| dist/lidar2map-*.zip | |
| dist/lidar2map-*.tar.gz | |
| dist/lidar2map-*.sha256 | |
| publish: | |
| name: publish release | |
| needs: build | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Download artefacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Composer le body + publier la release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| # GH_REPO : le job publish ne fait pas de checkout (pas de .git), | |
| # donc gh ne peut pas déduire le repo via git -> on le lui donne | |
| # explicitement, sinon "fatal: not a git repository". | |
| GH_REPO: ${{ github.repository }} | |
| TAG: ${{ inputs.tag || github.ref_name }} | |
| run: | | |
| set -euo pipefail | |
| # Collecter les assets (zip/tar.gz) et leurs SHA256 | |
| ASSETS=() | |
| BODY=$'## lidar2map '"$TAG"$'\n\nExécutables lidar2map. Python n’est pas requis sur le PC client. L’exécution distante sur VM (`--remote-cli` / `--remote-gui`) est embarquée, voir tools/README_rlidar2map.md.\n\nPremier lancement de lidar2map : extraction locale (~30-60 s). Mise à jour du script sans rebuild via `update_app.py`.\n\n| Fichier | SHA256 |\n|---|---|\n' | |
| while IFS= read -r sha; do | |
| asset="${sha%.sha256}" | |
| name="$(basename "$asset")" | |
| hash="$(tr -d '[:space:]' < "$sha")" | |
| BODY+="| \`$name\` | \`$hash\` |"$'\n' | |
| ASSETS+=("$asset") | |
| done < <(find artifacts -name '*.sha256' | sort) | |
| if [ "${#ASSETS[@]}" -eq 0 ]; then | |
| echo "ERREUR : aucun asset trouvé dans artifacts/" >&2 | |
| exit 1 | |
| fi | |
| printf '%s' "$BODY" > body.md | |
| echo "── Body de la release ──"; cat body.md | |
| echo "── Assets ──"; printf ' %s\n' "${ASSETS[@]}" | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| gh release edit "$TAG" --notes-file body.md | |
| gh release upload "$TAG" "${ASSETS[@]}" --clobber | |
| else | |
| gh release create "$TAG" "${ASSETS[@]}" \ | |
| --title "lidar2map $TAG" --notes-file body.md | |
| fi | |
| echo "Release $TAG publiée." |