feat(package): release assets that can actually be downloaded #79
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: Build Action self-tests | |
| permissions: | |
| contents: read | |
| concurrency: | |
| # One run per branch. A push supersedes the one before it, and the older run | |
| # is answering a question about code nobody has any more — so it is cancelled | |
| # rather than left to finish and report on a tree that no longer exists. | |
| # | |
| # Tags are exempt. A release build is not superseded by anything, and half a | |
| # release is worse than a slow one. | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }} | |
| on: | |
| push: | |
| branches: [ "main", "*-*" ] | |
| pull_request: | |
| branches: [ "main", "*-*" ] | |
| workflow_dispatch: | |
| jobs: | |
| # Structural checks on every action.yml. These catch the mistakes that pass | |
| # YAML validation and then fail quietly: an output declared without a value | |
| # resolves to "" forever with nothing warning about it, which is how one | |
| # misplaced line broke all seven discovery fixtures at once. | |
| action-contracts: | |
| name: Action contracts (outputs have values, inputs are described) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.x' | |
| - run: pip install --quiet pyyaml | |
| - run: python3 tests/action_contracts.py | |
| discovery-tests: | |
| name: Discovery sub-action tests on ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - id: disc | |
| uses: ./actions/discovery | |
| - name: Assert outputs (bash) | |
| if: runner.os != 'Windows' | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| : "${{ steps.disc.outputs.OS }}" | |
| : "${{ steps.disc.outputs.ARCH }}" | |
| : "${{ steps.disc.outputs.REF }}" | |
| : "${{ steps.disc.outputs.SHORT_SHA }}" | |
| echo "OS=${{ steps.disc.outputs.OS }} ARCH=${{ steps.disc.outputs.ARCH }} REF=${{ steps.disc.outputs.REF }} SHORT_SHA=${{ steps.disc.outputs.SHORT_SHA }}" | |
| - name: Assert outputs (pwsh) | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| run: | | |
| if (-not "${{ steps.disc.outputs.OS }}") { throw 'OS output empty' } | |
| if (-not "${{ steps.disc.outputs.ARCH }}") { throw 'ARCH output empty' } | |
| if (-not "${{ steps.disc.outputs.REF }}") { throw 'REF output empty' } | |
| if (-not "${{ steps.disc.outputs.SHORT_SHA }}") { throw 'SHORT_SHA output empty' } | |
| discovery-fixture-tests: | |
| name: Discovery fixture tests (project markers and stack suggestion) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { dir: 'tdd/wails2-root', expect: 'wails2', expect_root_pkg: '0', expect_frontend_pkg: '1', expect_go_mod: '1', expect_main_go: '1', expect_cmake: '0' } | |
| # v3 in the shape the real ones take: module in go/, frontend beside | |
| # it, Taskfile instead of CLI flags. Catches both things discovery got | |
| # wrong — a nested module read as "no Go", and Go+frontend read as v2. | |
| - { dir: 'tdd/wails3-root', expect: 'wails3', expect_root_pkg: '0', expect_frontend_pkg: '0', expect_go_mod: '1', expect_main_go: '0', expect_cmake: '0' } | |
| # A module with a main package builds a binary; one without is a | |
| # library. Different jobs, so different stacks. | |
| - { dir: 'tdd/go-cli', expect: 'go', expect_root_pkg: '0', expect_frontend_pkg: '0', expect_go_mod: '1', expect_main_go: '1', expect_cmake: '0' } | |
| - { dir: 'tdd/go-http', expect: 'go', expect_root_pkg: '0', expect_frontend_pkg: '0', expect_go_mod: '1', expect_main_go: '1', expect_cmake: '0' } | |
| # Runtime comes from the lockfile; framework is a separate axis. | |
| - { dir: 'tdd/node-astro', expect: 'node', expect_root_pkg: '1', expect_frontend_pkg: '0', expect_go_mod: '0', expect_main_go: '0', expect_cmake: '0' } | |
| # A Go library with a UI beside it and a dot-directory manifest. | |
| # This is dAppCore/go-build's shape, which discovery answered | |
| # 'wails2' for the first time it saw a real repository. | |
| - { dir: 'tdd/go-library-with-ui', expect: 'core', expect_root_pkg: '0', expect_frontend_pkg: '0', expect_go_mod: '1', expect_main_go: '0', expect_cmake: '0' } | |
| - { dir: 'tdd/node-pnpm', expect: 'node', expect_root_pkg: '1', expect_frontend_pkg: '0', expect_go_mod: '0', expect_main_go: '0', expect_cmake: '0' } | |
| - { dir: 'tdd/node-yarn', expect: 'node', expect_root_pkg: '1', expect_frontend_pkg: '0', expect_go_mod: '0', expect_main_go: '0', expect_cmake: '0' } | |
| - { dir: 'tdd/deno-danet', expect: 'deno', expect_root_pkg: '0', expect_frontend_pkg: '0', expect_go_mod: '0', expect_main_go: '0', expect_cmake: '0' } | |
| - { dir: 'tdd/cpp-root', expect: 'cpp', expect_root_pkg: '0', expect_frontend_pkg: '0', expect_go_mod: '0', expect_main_go: '0', expect_cmake: '1' } | |
| - { dir: 'tdd/node-only', expect: 'node', expect_root_pkg: '1', expect_frontend_pkg: '0', expect_go_mod: '0', expect_main_go: '0', expect_cmake: '0' } | |
| - { dir: 'tdd/docs', expect: 'unknown', expect_root_pkg: '0', expect_frontend_pkg: '0', expect_go_mod: '0', expect_main_go: '0', expect_cmake: '0' } | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - id: disc | |
| uses: ./actions/discovery | |
| with: | |
| working-directory: ${{ matrix.dir }} | |
| - name: Assert markers and suggestion | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| echo "[DEBUG_LOG] Tested dir=${{ matrix.dir }}" | |
| test "${{ steps.disc.outputs.PRIMARY_STACK_SUGGESTION }}" = "${{ matrix.expect }}" | |
| test "${{ steps.disc.outputs.HAS_ROOT_PACKAGE_JSON }}" = "${{ matrix.expect_root_pkg }}" | |
| test "${{ steps.disc.outputs.HAS_FRONTEND_PACKAGE_JSON }}" = "${{ matrix.expect_frontend_pkg }}" | |
| test "${{ steps.disc.outputs.HAS_ROOT_GO_MOD }}" = "${{ matrix.expect_go_mod }}" | |
| test "${{ steps.disc.outputs.HAS_ROOT_MAIN_GO }}" = "${{ matrix.expect_main_go }}" | |
| test "${{ steps.disc.outputs.HAS_ROOT_CMAKELISTS }}" = "${{ matrix.expect_cmake }}" | |
| options-tests: | |
| name: Options sub-action matrix (Ubuntu) | |
| needs: [action-contracts, discovery-tests, discovery-fixture-tests] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { distro: '22.04', obf: 'false', nsis: 'false', tags: 'false', expect_webkit: 'false' } | |
| - { distro: '24.04', obf: 'false', nsis: 'false', tags: 'false', expect_webkit: 'true' } | |
| - { distro: '24.04', obf: 'true', nsis: 'true', tags: 'release', expect_webkit: 'true' } | |
| - { distro: '24.04', obf: 'false', nsis: 'false', tags: 'release,custom,custom', expect_webkit: 'true', expect_dedupe: 'custom' } | |
| - { distro: '24.04', obf: 'false', nsis: 'false', tags: 'release custom', expect_webkit: 'true', expect_dedupe: '' } | |
| - { distro: '24.04', obf: 'false', nsis: 'false', tags: 'false', expect_webkit: 'false', disable_webkit: 'true' } | |
| # -debug, -ldflags and -windowsconsole, from #44. ldflags is quoted | |
| # as one argument because several flags separated by spaces are the | |
| # normal case. | |
| - { distro: '22.04', obf: 'false', nsis: 'false', tags: 'false', expect_webkit: 'false', debug: 'true', expect_flag: '-debug' } | |
| - { distro: '22.04', obf: 'false', nsis: 'false', tags: 'false', expect_webkit: 'false', windowsconsole: 'true', expect_flag: '-windowsconsole' } | |
| - { distro: '22.04', obf: 'false', nsis: 'false', tags: 'false', expect_webkit: 'false', ldflags: '-X=main.Version=1.2.3 -s', expect_flag: "-ldflags='-X=main.Version=1.2.3 -s'" } | |
| # upx, from #48 — the flags travel as one quoted argument for the | |
| # same reason ldflags does. | |
| - { distro: '22.04', obf: 'false', nsis: 'false', tags: 'false', expect_webkit: 'false', upx: 'true', expect_flag: '-upx' } | |
| - { distro: '22.04', obf: 'false', nsis: 'false', tags: 'false', expect_webkit: 'false', upx: 'true', upx_flags: '--best --lzma', expect_flag: "-upxflags='--best --lzma'" } | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - id: opts | |
| uses: ./actions/options | |
| with: | |
| build-obfuscate: ${{ matrix.obf }} | |
| build-tags: ${{ matrix.tags }} | |
| nsis: ${{ matrix.nsis }} | |
| distro: ${{ matrix.distro }} | |
| disable-webkit-auto-tag: ${{ matrix.disable_webkit || 'false' }} | |
| build-debug: ${{ matrix.debug || 'false' }} | |
| build-windowsconsole: ${{ matrix.windowsconsole || 'false' }} | |
| build-ldflags: ${{ matrix.ldflags || 'false' }} | |
| upx: ${{ matrix.upx || 'false' }} | |
| upx-flags: ${{ matrix.upx_flags || '' }} | |
| - name: Assert BUILD_OPTIONS | |
| shell: bash | |
| env: | |
| # Through env, not interpolation: -upxflags='--best --lzma' contains | |
| # quotes, and pasting that inside a shell assignment mangles it. | |
| BUILD_OPTIONS: ${{ steps.opts.outputs.BUILD_OPTIONS }} | |
| EXPECT_FLAG: ${{ matrix.expect_flag || '' }} | |
| run: | | |
| set -euo pipefail | |
| BO="$BUILD_OPTIONS" | |
| echo "BUILD_OPTIONS=$BO" | |
| if [ "${{ matrix.obf }}" = "true" ] && ! echo "$BO" | grep -q -- "-obfuscated"; then echo "missing -obfuscated"; exit 1; fi | |
| if [ "${{ matrix.nsis }}" = "true" ] && ! echo "$BO" | grep -q -- "-nsis"; then echo "missing -nsis"; exit 1; fi | |
| if [ "${{ matrix.expect_webkit }}" = "true" ] && ! echo "$BO" | grep -q -- "webkit2_41"; then echo "missing webkit2_41"; exit 1; fi | |
| if [ "${{ matrix.disable_webkit || 'false' }}" = "true" ] && echo "$BO" | grep -q -- "webkit2_41"; then echo "webkit2_41 should be disabled"; exit 1; fi | |
| if [ -n "$EXPECT_FLAG" ]; then | |
| case "$BO" in | |
| *"$EXPECT_FLAG"*) : ;; | |
| *) echo "missing $EXPECT_FLAG"; exit 1 ;; | |
| esac | |
| fi | |
| if [ -n "${{ matrix.expect_dedupe || '' }}" ]; then | |
| count=$(echo "$BO" | grep -o -- "${{ matrix.expect_dedupe }}" | wc -l | tr -d ' ') | |
| if [ "$count" -ne 1 ]; then echo "expected tag '${{ matrix.expect_dedupe }}' to appear once, got $count"; exit 1; fi | |
| fi | |
| setup-go-tests: | |
| needs: [options-tests, wails-env-mapping, wails-env-mapping-wrapper] | |
| name: Setup Go/Wails sub-action on ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Go/Wails | |
| uses: ./actions/setup/go | |
| with: | |
| go-version: '1.23' | |
| build-cache: 'true' | |
| build-obfuscate: 'false' | |
| wails-version: 'latest' | |
| wails-dev-build: 'false' | |
| - name: Assert go and wails available | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| go version | |
| if command -v wails >/dev/null 2>&1; then wails version || true; else echo "wails not on PATH (may be Windows PATH nuance), continuing"; fi | |
| setup-npm-tests: | |
| name: Setup npm sub-action on ${{ matrix.os }} | |
| needs: [options-tests, wails-env-mapping, wails-env-mapping-wrapper] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node/npm (no install) | |
| uses: ./actions/setup/npm | |
| with: | |
| node-version: '18.x' | |
| working-directory: '.' | |
| install: 'false' | |
| - name: Assert node/npm | |
| shell: bash | |
| run: | | |
| node -v | |
| npm -v | |
| setup-conan-tests: | |
| needs: [options-tests, wails-env-mapping, wails-env-mapping-wrapper] | |
| name: Setup Conan sub-action (Linux only) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Conan | |
| uses: ./actions/setup/conan | |
| - name: Assert conan is on PATH | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| # This used to pass either way — "Conan not found in PATH (ok for | |
| # placeholder)". Conan is not a placeholder any more; the cpp stack | |
| # calls it, so not finding it is a failure. | |
| conan --version | |
| # setup-deno-tests: | |
| # name: Setup Deno sub-action behavior (skip vs enable) | |
| # runs-on: ubuntu-latest | |
| # steps: | |
| # - uses: actions/checkout@v4 | |
| # - name: Skip path (no env) | |
| # uses: ./actions/setup/deno | |
| # - name: Enable via env and run a command | |
| # env: | |
| # DENO_ENABLE: 'true' | |
| # DENO_VERSION: 'v1.44.x' | |
| # DENO_WORKDIR: '.' | |
| # DENO_BUILD: 'deno --version' | |
| # uses: ./actions/setup/deno | |
| package-tests: | |
| needs: [setup-conan-tests,setup-go-tests,setup-npm-tests] | |
| name: Package sub-action with dummy artifact (Ubuntu) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Prepare dummy artifact | |
| shell: bash | |
| run: | | |
| mkdir -p tmp/bin | |
| echo "hello" > tmp/bin/dummy.txt | |
| - name: Package (no release on branches) | |
| uses: ./actions/package | |
| with: | |
| package: 'true' | |
| build-name: 'ci-test' | |
| os: 'Linux' | |
| arch: 'amd64' | |
| short-sha: '${{ github.sha }}' | |
| - name: Check log | |
| run: echo "Ensure [DEBUG_LOG] ARTIFACT_NAME is visible above" | |
| package-smoke-ubuntu: | |
| name: Packaging smoke (Ubuntu, package:true, no release on non-tags) | |
| runs-on: ubuntu-latest | |
| needs: package-tests | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Prepare dummy artifact | |
| shell: bash | |
| run: | | |
| mkdir -p tmp/bin | |
| echo "dummy" > tmp/bin/dummy.txt | |
| - name: Run root action with packaging | |
| uses: ./ | |
| with: | |
| build-name: wails-smoke-${{ github.run_id }} | |
| build-platform: linux/amd64 | |
| app-working-directory: tdd/wails2-root | |
| package: true | |
| sign: false | |
| nsis: false | |
| - name: Note | |
| run: | | |
| echo "[DEBUG_LOG] Packaging smoke complete. Check previous step for ARTIFACT_NAME echo." | |
| signing-diagnostics: | |
| name: Signing diagnostics (dry-run) | |
| needs: package-tests | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: macOS signing tool discovery | |
| if: runner.os == 'macOS' | |
| shell: bash | |
| run: | | |
| # Diagnostic, so it reports and stays green either way — a runner | |
| # without these is a fact worth seeing before a release depends on it. | |
| if command -v codesign >/dev/null 2>&1; then | |
| echo "[DEBUG_LOG] codesign: $(codesign --version 2>&1 | head -1)" | |
| else | |
| echo "[DEBUG_LOG] codesign not found" | |
| fi | |
| if xcrun notarytool --version >/dev/null 2>&1; then | |
| echo "[DEBUG_LOG] notarytool: $(xcrun notarytool --version 2>&1 | head -1)" | |
| else | |
| echo "[DEBUG_LOG] notarytool not found — notarisation would fail on a tag" | |
| fi | |
| - name: Windows signtool discovery | |
| if: runner.os == 'Windows' | |
| shell: powershell | |
| run: | | |
| $paths = @( | |
| 'C:/Program Files (x86)/Windows Kits/10/bin', | |
| 'C:/Program Files (x86)/Windows Kits/11/bin' | |
| ) | |
| $found = $false | |
| foreach ($base in $paths) { | |
| if (Test-Path $base) { | |
| $sig = Get-ChildItem -Path $base -Recurse -Filter signtool.exe -ErrorAction SilentlyContinue | Select-Object -First 1 | |
| if ($sig) { Write-Host "[DEBUG_LOG] signtool found at $($sig.FullName)"; $found = $true; break } | |
| } | |
| } | |
| if (-not $found) { | |
| Write-Host "[DEBUG_LOG] signtool.exe not found in common SDK paths. It is typically available with Windows 10/11 SDK." | |
| } | |
| subactions-smoke: | |
| needs: package-tests | |
| name: Sub-actions smoke (workflow-local ./actions/*) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Discovery (workflow-local path) | |
| id: disc | |
| uses: ./actions/discovery | |
| - name: Compute options (with distro) | |
| id: opts | |
| uses: ./actions/options | |
| with: | |
| build-obfuscate: 'true' | |
| build-tags: 'release' | |
| nsis: 'false' | |
| distro: ${{ steps.disc.outputs.DISTRO }} | |
| - name: Show computed options | |
| run: echo "BUILD_OPTIONS='${{ steps.opts.outputs.BUILD_OPTIONS }}'" | |
| auto-stack-smoke: | |
| needs: package-tests | |
| name: Auto stack routing smoke (root action on Wails2-like repo) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Run root action with AUTO_STACK in tdd/wails2-root | |
| id: root | |
| uses: ./ | |
| with: | |
| build-name: wails | |
| build-platform: linux/amd64 | |
| app-working-directory: tdd/wails2-root | |
| build: false | |
| package: false | |
| sign: false | |
| - name: Assert orchestrator selected wails2 | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| sel='${{ steps.root.outputs.SELECTED_STACK }}' | |
| echo "[DEBUG_LOG] SELECTED_STACK=$sel" | |
| test "$sel" = "wails2" || { echo "Expected SELECTED_STACK=wails2, got '$sel'"; exit 1; } | |
| matrix-root-action: | |
| name: Root action (./) on ${{ matrix.os }} for ${{ matrix.platform }} | |
| runs-on: ${{ matrix.os }} | |
| needs: [ package-tests] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| platform: linux/amd64 | |
| - os: windows-latest | |
| platform: windows/amd64 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Prepare dummy artifact | |
| shell: bash | |
| run: | | |
| mkdir -p tmp/bin | |
| echo "dummy" > tmp/bin/dummy.txt | |
| - name: Run root action locally | |
| uses: ./ | |
| with: | |
| build-name: wails-root-action-${{ matrix.os }} | |
| build-platform: ${{ matrix.platform }} | |
| app-working-directory: tdd/wails2-root | |
| build: false | |
| package: true | |
| sign: false | |
| wrapper-wails2: | |
| name: Wails2 wrapper (./actions/build/wails2) on ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| needs: [package-tests] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| platform: linux/amd64 | |
| - os: windows-latest | |
| platform: windows/amd64 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Run wails2 wrapper locally | |
| uses: ./actions/build/wails2 | |
| with: | |
| build-name: wails-wrapper-${{ matrix.os }} | |
| build-platform: ${{ matrix.platform }} | |
| app-working-directory: tdd/wails2-root | |
| package: true | |
| sign: false | |
| nsis: false | |
| # deno-env-path-test: | |
| # name: Deno env-first path (root action on Ubuntu) | |
| # runs-on: ubuntu-latest | |
| # steps: | |
| # - uses: actions/checkout@v4 | |
| # - name: Configure Deno via $GITHUB_ENV | |
| # run: | | |
| # echo "DENO_ENABLE=true" >> "$GITHUB_ENV" | |
| # echo "DENO_VERSION=v1.44.x" >> "$GITHUB_ENV" | |
| # echo "DENO_WORKDIR=frontend" >> "$GITHUB_ENV" | |
| # echo "DENO_BUILD=deno --version" >> "$GITHUB_ENV" | |
| # - name: Run root action (should set up Deno and run command) | |
| # uses: ./ | |
| # with: | |
| # build-name: wails | |
| # build-platform: linux/amd64 | |
| # build: false | |
| # package: false | |
| wails-env-mapping: | |
| name: WAILS_* env mapping (root action) | |
| needs: [action-contracts, discovery-tests, discovery-fixture-tests] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Configure WAILS_* via $GITHUB_ENV | |
| run: | | |
| echo "WAILS_OBFUSCATE=true" >> "$GITHUB_ENV" | |
| echo "WAILS_NSIS=false" >> "$GITHUB_ENV" | |
| echo "WAILS_BUILD_TAGS=release custom" >> "$GITHUB_ENV" | |
| echo "WAILS_VERSION=latest" >> "$GITHUB_ENV" | |
| echo "WAILS_GO_VERSION=1.23" >> "$GITHUB_ENV" | |
| echo "WAILS_NODE_VERSION=18.x" >> "$GITHUB_ENV" | |
| echo "WAILS_WEBVIEW2=download" >> "$GITHUB_ENV" | |
| - name: Run root action (uses ENV mapping) | |
| uses: ./ | |
| with: | |
| build-name: wails | |
| build-platform: linux/amd64 | |
| app-working-directory: tdd/wails2-root | |
| build: false | |
| package: false | |
| sign: false | |
| wails-env-mapping-wrapper: | |
| name: WAILS_* env mapping (wrapper outputs) | |
| needs: [action-contracts, discovery-tests, discovery-fixture-tests] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Configure WAILS_* via $GITHUB_ENV (wrapper) | |
| run: | | |
| echo "WAILS_OBFUSCATE=true" >> "$GITHUB_ENV" | |
| echo "WAILS_NSIS=false" >> "$GITHUB_ENV" | |
| echo "WAILS_BUILD_TAGS=release custom" >> "$GITHUB_ENV" | |
| echo "WAILS_VERSION=latest" >> "$GITHUB_ENV" | |
| echo "WAILS_GO_VERSION=1.23" >> "$GITHUB_ENV" | |
| echo "WAILS_NODE_VERSION=18.x" >> "$GITHUB_ENV" | |
| echo "WAILS_WEBVIEW2=download" >> "$GITHUB_ENV" | |
| - name: Run wails2 wrapper (capture outputs) | |
| id: wrap | |
| uses: ./actions/build/wails2 | |
| with: | |
| build-name: wails-wrapper-${{ github.run_id }} | |
| build-platform: linux/amd64 | |
| app-working-directory: tdd/wails2-root | |
| build: false | |
| package: false | |
| sign: false | |
| nsis: false | |
| - name: Assert wrapper resolved envs | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| tags='${{ steps.wrap.outputs.BUILD_TAGS }}' | |
| obf='${{ steps.wrap.outputs.OBFUSCATE }}' | |
| nsis='${{ steps.wrap.outputs.NSIS }}' | |
| echo "[DEBUG_LOG] WRAP_BUILD_TAGS=$tags OBFUSCATE=$obf NSIS=$nsis" | |
| grep -q "release" <<< "$tags" | |
| grep -q "custom" <<< "$tags" | |
| test "$obf" = "true" | |
| test "$nsis" = "false" | |
| readme-snippets: | |
| name: README snippets validation (non-signing, non-release) | |
| needs: [package-tests] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Discovery example | |
| id: disc | |
| uses: ./actions/discovery | |
| with: | |
| working-directory: tdd/wails2-root | |
| - name: Options example | |
| id: opts | |
| uses: ./actions/options | |
| with: | |
| build-obfuscate: 'true' | |
| build-tags: 'release' | |
| nsis: 'false' | |
| distro: ${{ steps.disc.outputs.DISTRO }} | |
| - name: Package example | |
| uses: ./actions/package | |
| with: | |
| package: 'true' | |
| build-name: 'ci-snippet' | |
| os: 'Linux' | |
| arch: 'amd64' | |
| short-sha: '${{ github.sha }}' | |
| include-meta: 'true' | |
| - name: Note | |
| run: echo "[DEBUG_LOG] README snippets validated" | |
| # Every other job runs the actions from `./` — the tree under test. That | |
| # proves the code, and proves nothing about the name people actually type. | |
| # The wrappers reach for each other as `dAppCore/build/actions/…@v4`, and | |
| # those references are unresolvable until the tag exists, so this is the one | |
| # check that has to consume the published tag rather than the checkout. | |
| published-tag: | |
| name: Published dAppCore/build@v4 resolves | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Discovery, from the tag | |
| id: disc | |
| uses: dAppCore/build/actions/discovery@v4 | |
| with: | |
| working-directory: tdd/wails3-root | |
| - name: Assert the published tree answers | |
| shell: bash | |
| env: | |
| GOT: ${{ steps.disc.outputs.PRIMARY_STACK_SUGGESTION }} | |
| run: | | |
| set -euo pipefail | |
| echo "[DEBUG_LOG] @v4 discovery says: $GOT" | |
| test "$GOT" = "wails3" | |
| build-wails2: | |
| name: Build Wails2 project (actual compilation) | |
| needs: [setup-go-tests, setup-npm-tests] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build with action | |
| uses: ./ | |
| with: | |
| build-name: hello-wails | |
| build-platform: linux/arm64 | |
| app-working-directory: tdd/wails2-root | |
| build: true | |
| package: false | |
| sign: false | |
| - name: Verify binary | |
| run: test -f tdd/wails2-root/build/bin/hello-wails | |
| # Until this job existed, every wails3 reference in CI was a discovery | |
| # assertion: the stack was detected, routed to and tagged, with nothing | |
| # showing it could compile anything. The fixture links wails/v3's application | |
| # package, so this exercises the real cgo and webview toolchain — on Linux | |
| # that is GTK4 and webkitgtk-6.0, which is precisely where the stack is | |
| # easiest to get wrong. | |
| # The application this stack exists for — Lethean's blockchain — pulls boost, | |
| # openssl and oatpp and takes about an hour to compile. Nothing about that | |
| # duration tests the action, so the fixture mirrors the shape (Conan 2 with a | |
| # generated toolchain, CMakeDeps, an msvc-aware layout, CTest) with | |
| # dependencies that resolve in seconds. | |
| # The plain case, and the one most Go repositories actually are: a module, a | |
| # main package, a binary. Cross-compilation is covered here rather than in a | |
| # separate job because `go build` needs no toolchain for it as long as cgo is | |
| # off — which is the one thing worth asserting. | |
| build-go: | |
| name: Build Go binary (actual compilation) on ${{ matrix.os }} | |
| needs: [discovery-tests, discovery-fixture-tests] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build with the go stack | |
| id: go | |
| uses: ./actions/build/go | |
| with: | |
| build-name: hello | |
| app-working-directory: tdd/go-cli | |
| build: true | |
| package: false | |
| sign: false | |
| # test defaults to auto; asked for explicitly here because the point | |
| # of this job is that tests ran, not that they were skipped quietly. | |
| test: 'true' | |
| coverage: 'true' | |
| coverage-threshold: '40' | |
| benchmarks: 'true' | |
| - name: Assert the tests actually ran and reported coverage | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| test "${{ steps.go.outputs.COVERAGE }}" != "" | |
| echo "[DEBUG_LOG] coverage=${{ steps.go.outputs.COVERAGE }}%" | |
| test -f tdd/go-cli/coverage.out | |
| test -f tdd/go-cli/benchmarks.txt | |
| grep -q "^BenchmarkGreet" tdd/go-cli/benchmarks.txt | |
| - name: Verify the binary runs | |
| shell: bash | |
| working-directory: tdd/go-cli | |
| run: | | |
| set -euo pipefail | |
| out="$(./${{ steps.go.outputs.BINARY_PATH }})" | |
| echo "[DEBUG_LOG] go fixture said: $out" | |
| echo "$out" | grep -q "Hello" | |
| - name: Cross-compile to a platform this runner is not | |
| uses: ./actions/build/go/build | |
| with: | |
| build-name: hello-cross | |
| app-working-directory: tdd/go-http | |
| build-platform: ${{ runner.os == 'Linux' && 'windows/amd64' || 'linux/arm64' }} | |
| cgo: '0' | |
| - name: Verify the cross-built file exists and is for the other platform | |
| shell: bash | |
| working-directory: tdd/go-http | |
| run: | | |
| set -euo pipefail | |
| # Named by target, not by runner — a windows cross-build gets .exe | |
| # even from Linux. | |
| ls -la bin/ | |
| if [ "${RUNNER_OS}" = "Linux" ]; then test -f bin/hello-cross.exe; else test -f bin/hello-cross; fi | |
| # The other half of the contract: a module with no tests is not a failure | |
| # under auto, and the skip is announced rather than silent. | |
| go-without-tests: | |
| name: Go stack on a module with no tests | |
| needs: [action-contracts] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build a module that has no *_test.go | |
| id: go | |
| uses: ./actions/build/go | |
| with: | |
| build-name: hello-http | |
| app-working-directory: tdd/go-http | |
| package: false | |
| sign: false | |
| - name: Assert it detected no tests and built anyway | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| test -f "tdd/go-http/${{ steps.go.outputs.BINARY_PATH }}" | |
| echo "[DEBUG_LOG] built without tests, as expected" | |
| build-node: | |
| name: Build Node project (Astro) on ${{ matrix.os }} | |
| needs: [action-contracts, discovery-fixture-tests] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build with the node stack | |
| id: node | |
| uses: ./actions/build/node | |
| with: | |
| build-name: astro-fixture | |
| app-working-directory: tdd/node-astro | |
| package: false | |
| - name: Assert the astro adapter ran and found dist | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| test "${{ steps.node.outputs.FRAMEWORK }}" = "astro" | |
| test "${{ steps.node.outputs.OUTPUT_PATH }}" = "dist" | |
| test -f tdd/node-astro/dist/index.html | |
| grep -q "Built by dAppCore/build" tdd/node-astro/dist/index.html | |
| # Package managers are not runtimes: pnpm and yarn install a Node tree the | |
| # same package.json describes. What differs is the lockfile and the spelling | |
| # of "use it and refuse to change it" — npm ci, pnpm --frozen-lockfile, | |
| # yarn --immutable at v2 and --frozen-lockfile at v1. Each fixture commits a | |
| # real lockfile so those paths are actually taken. | |
| build-node-package-managers: | |
| name: Node stack with ${{ matrix.pm }} | |
| needs: [action-contracts, discovery-fixture-tests] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| pm: [pnpm, yarn] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build with the node stack | |
| id: node | |
| uses: ./actions/build/node | |
| with: | |
| build-name: ${{ matrix.pm }}-fixture | |
| app-working-directory: tdd/node-${{ matrix.pm }} | |
| package: false | |
| - name: Assert the right manager ran | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| test "${{ steps.node.outputs.PACKAGE_MANAGER }}" = "${{ matrix.pm }}" | |
| test "${{ steps.node.outputs.OUTPUT_PATH }}" = "dist" | |
| test -f "tdd/node-${{ matrix.pm }}/dist/index.html" | |
| build-deno: | |
| name: Build Deno project (Danet) on ${{ matrix.os }} | |
| needs: [action-contracts, discovery-fixture-tests] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build with the deno stack | |
| id: deno | |
| uses: ./actions/build/deno | |
| with: | |
| build-name: danet-fixture | |
| app-working-directory: tdd/deno-danet | |
| package: false | |
| - name: Assert the danet adapter compiled a runnable binary | |
| shell: bash | |
| working-directory: tdd/deno-danet | |
| run: | | |
| set -euo pipefail | |
| test "${{ steps.deno.outputs.FRAMEWORK }}" = "danet" | |
| out="$(./${{ steps.deno.outputs.BINARY_PATH }})" | |
| echo "[DEBUG_LOG] danet fixture said: $out" | |
| # The binary bootstraps the module and registers the route before it | |
| # prints, so this line only appears if the decorators really worked. | |
| echo "$out" | grep -q "danet-fixture ok" | |
| build-cpp: | |
| name: Build C++ project (actual compilation) on ${{ matrix.os }} | |
| needs: [discovery-tests, discovery-fixture-tests] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build with the cpp stack | |
| id: cpp | |
| uses: ./actions/build/cpp | |
| with: | |
| build-name: cpp-fixture | |
| app-working-directory: tdd/cpp-root | |
| build: true | |
| package: false | |
| sign: false | |
| - name: Verify the binary runs | |
| shell: bash | |
| working-directory: tdd/cpp-root | |
| run: | | |
| set -euo pipefail | |
| out="$(./${{ steps.cpp.outputs.BINARY_PATH }})" | |
| echo "[DEBUG_LOG] fixture said: $out" | |
| # It links zlib and includes nlohmann_json, so seeing both in the | |
| # output proves the Conan half resolved rather than just that a | |
| # compiler ran. | |
| echo "$out" | grep -q '"zlib"' | |
| echo "$out" | grep -q '"json"' | |
| build-wails3: | |
| name: Build Wails3 project (actual compilation) on ${{ matrix.os }} | |
| needs: [setup-go-tests, setup-npm-tests] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - { os: ubuntu-latest, binary: 'bin/wails3-fixture' } | |
| - { os: macos-latest, binary: 'bin/wails3-fixture' } | |
| - { os: windows-latest, binary: 'bin/wails3-fixture.exe' } | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Build with the wails3 stack | |
| uses: ./actions/build/wails3 | |
| with: | |
| build-name: wails3-fixture | |
| app-working-directory: tdd/wails3-root | |
| npm-working-directory: tdd/wails3-root/frontend-ng | |
| build: true | |
| package: false | |
| sign: false | |
| - name: Verify binary | |
| shell: bash | |
| run: test -f "tdd/wails3-root/${{ matrix.binary }}" |