diff --git a/.github/workflows/build-and-package.yml b/.github/workflows/build-and-package.yml new file mode 100644 index 00000000..a83fd264 --- /dev/null +++ b/.github/workflows/build-and-package.yml @@ -0,0 +1,201 @@ +--- +name: Build and Package + +'on': + workflow_call: + inputs: + platform: + description: Operating system family for the build. + required: true + type: string + runner: + description: GitHub-hosted runner label to target. + required: true + type: string + target: + description: Cargo build target triple. + required: true + type: string + artifact_label: + description: Suffix used when naming uploaded artefacts. + required: true + type: string + package_arch: + description: Package architecture label used for artefact naming. + required: false + type: string + target_key: + description: Release staging target key for macOS and Windows builds. + required: false + type: string + msi_arch: + description: WiX architecture identifier for Windows installer builds. + required: false + type: string + repo_name: + description: Repository name used when uploading artefacts. + required: true + type: string + bin_name: + description: Binary name extracted from Cargo metadata. + required: true + type: string + version: + description: Crate version extracted from Cargo metadata. + required: true + type: string + should_publish: + description: Whether artefacts should be published. + required: true + type: boolean + wix_extension_version: + description: WiX extension version required for Windows packaging. + required: false + type: string + +jobs: + build-and-package: + name: Build and package ${{ inputs.platform }} (${{ inputs.target }}) + runs-on: ${{ inputs.runner }} + env: + REPO_NAME: ${{ inputs.repo_name }} + BIN_NAME: ${{ inputs.bin_name }} + VERSION: ${{ inputs.version }} + steps: + - uses: >- + actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 + # v4.1.2 + + - name: Install uv + if: inputs.platform != 'linux' + uses: >- + astral-sh/setup-uv@4cda7d73322c50eac316ad623a716f09a2db2ac7 + # v3.1.2 + with: + python-version: '3.11' + + - name: Build release + uses: >- + leynos/shared-actions/.github/actions/rust-build-release@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b + with: + target: ${{ inputs.target }} + bin-name: ${{ inputs.bin_name }} + version: ${{ inputs.version }} + + - name: Package Linux artefacts with dependencies + if: inputs.platform == 'linux' + uses: >- + leynos/shared-actions/.github/actions/linux-packages@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b + with: + project-dir: . + package-name: ${{ inputs.bin_name }} + bin-name: ${{ inputs.bin_name }} + target: ${{ inputs.target }} + version: ${{ inputs.version }} + formats: deb,rpm + man-paths: >- + dist/${{ inputs.bin_name }}_linux_${{ inputs.package_arch }}/${{ inputs.bin_name }}.1 + outdir: dist + deb-depends: ninja-build + rpm-depends: ninja-build + + - name: Prune packaging metadata + if: inputs.platform == 'linux' + shell: bash + run: rm -rf dist/.man dist/nfpm.yaml + + - id: stage + if: inputs.platform != 'linux' + name: Stage artefacts + uses: ./.github/actions/stage + with: + config-file: .github/release-staging.toml + target: ${{ inputs.target_key }} + + - id: normalize_windows_paths + if: inputs.platform == 'windows' + name: Normalise Windows paths + shell: bash + env: + BINARY_PATH: ${{ steps.stage.outputs.binary_path }} + LICENSE_PATH: ${{ steps.stage.outputs.license_path }} + run: | + set -euo pipefail + python .github/workflows/scripts/normalise_windows_paths.py + + - id: package_windows + if: inputs.platform == 'windows' + name: Build Windows installer package + uses: >- + leynos/shared-actions/.github/actions/windows-package@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b + with: + product-name: ${{ inputs.bin_name }} + manufacturer: Leynos + install-dir-name: ${{ inputs.bin_name }} + application-path: ${{ steps.normalize_windows_paths.outputs.binary_path }} + license-rtf-path: ${{ steps.normalize_windows_paths.outputs.license_path }} + architecture: ${{ inputs.msi_arch }} + version: ${{ inputs.version }} + output-basename: ${{ inputs.bin_name }} + output-directory: dist + license-plaintext-path: LICENSE + upload-artifact: ${{ inputs.should_publish }} + wix-extension-version: ${{ inputs.wix_extension_version }} + + - id: pkg + if: inputs.platform == 'macos' + name: Build macOS installer package + uses: >- + leynos/shared-actions/.github/actions/macos-package@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b + with: + name: ${{ inputs.bin_name }} + identifier: com.leynos.${{ inputs.bin_name }} + binary: ${{ steps.stage.outputs.binary_path }} + manpage: ${{ steps.stage.outputs.man_path }} + license-file: LICENSE + version: ${{ inputs.version }} + + - name: Stamp architecture into package name + if: inputs.platform == 'macos' + shell: bash + env: + BIN_NAME: ${{ inputs.bin_name }} + VERSION: ${{ inputs.version }} + ARCHIVE_SUFFIX: ${{ inputs.artifact_label }} + PKG_PATH: ${{ steps.pkg.outputs.pkg-path }} + run: | + set -euo pipefail + dest="dist/${BIN_NAME}-${VERSION}-${ARCHIVE_SUFFIX}.pkg" + mkdir -p "$(dirname "$dest")" + mv "$PKG_PATH" "$dest" + + - name: Upload Linux artefacts + if: inputs.platform == 'linux' + uses: >- + actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + # v4 + with: + name: ${{ inputs.repo_name }}-${{ inputs.artifact_label }} + path: dist + + - name: Upload Windows artefacts + if: inputs.platform == 'windows' && inputs.should_publish + uses: >- + actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + # v4 + with: + name: ${{ inputs.repo_name }}-${{ inputs.artifact_label }} + path: | + ${{ steps.stage.outputs.artifact_dir }} + ${{ steps.package_windows.outputs.msi-path }} + + - name: Upload macOS artefacts + if: inputs.platform == 'macos' + uses: >- + actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + # v4 + with: + name: ${{ inputs.repo_name }}-${{ inputs.artifact_label }} + path: | + ${{ steps.stage.outputs.artifact_dir }} + dist/${{ inputs.bin_name }}-${{ inputs.version }}-${{ inputs.artifact_label }}.pkg diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index de1e2b2d..9d3c7dc2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -114,7 +114,6 @@ jobs: build-linux: needs: metadata - runs-on: ubuntu-latest strategy: matrix: include: @@ -124,48 +123,20 @@ jobs: - target: aarch64-unknown-linux-gnu artifact: linux-arm64 package_arch: arm64 - steps: - - uses: >- - actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - # v4.1.2 - - name: Build Linux release - uses: >- - leynos/shared-actions/.github/actions/rust-build-release@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b - with: - target: ${{ matrix.target }} - bin-name: ${{ needs.metadata.outputs.bin_name }} - version: ${{ needs.metadata.outputs.version }} - # Package formats are produced by linux-packages below - - name: Package Linux artefacts with dependencies - uses: >- - leynos/shared-actions/.github/actions/linux-packages@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b - with: - project-dir: . - package-name: ${{ needs.metadata.outputs.bin_name }} - bin-name: ${{ needs.metadata.outputs.bin_name }} - target: ${{ matrix.target }} - version: ${{ needs.metadata.outputs.version }} - formats: deb,rpm - man-paths: >- - dist/${{ needs.metadata.outputs.bin_name }}_linux_${{ - matrix.package_arch }}/${{ needs.metadata.outputs.bin_name }}.1 - outdir: dist - deb-depends: ninja-build - rpm-depends: ninja-build - - name: Prune packaging metadata - shell: bash - run: rm -rf dist/.man dist/nfpm.yaml - - name: Upload Linux artefacts - uses: >- - actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - # v4 - with: - name: ${{ env.REPO_NAME }}-${{ matrix.artifact }} - path: dist + uses: ./.github/workflows/build-and-package.yml + with: + platform: linux + runner: ubuntu-latest + target: ${{ matrix.target }} + artifact_label: ${{ matrix.artifact }} + package_arch: ${{ matrix.package_arch }} + repo_name: ${{ env.REPO_NAME }} + bin_name: ${{ needs.metadata.outputs.bin_name }} + version: ${{ needs.metadata.outputs.version }} + should_publish: ${{ fromJSON(needs.metadata.outputs.should_publish) }} build-windows: needs: metadata - runs-on: windows-latest strategy: matrix: include: @@ -177,67 +148,20 @@ jobs: package_arch: arm64 msi_arch: arm64 target_key: windows-aarch64 - steps: - - uses: >- - actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - # v4.1.2 - - name: Install uv - uses: >- - astral-sh/setup-uv@4cda7d73322c50eac316ad623a716f09a2db2ac7 - # v3.1.2 - with: - python-version: '3.11' - - name: Build Windows release - uses: >- - leynos/shared-actions/.github/actions/rust-build-release@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b - with: - target: ${{ matrix.target }} - bin-name: ${{ needs.metadata.outputs.bin_name }} - version: ${{ needs.metadata.outputs.version }} - - id: stage - name: Stage Windows artefacts - uses: ./.github/actions/stage - with: - config-file: .github/release-staging.toml - target: ${{ matrix.target_key }} - - id: normalize_windows_paths - name: Normalise Windows paths - shell: bash - env: - BINARY_PATH: ${{ steps.stage.outputs.binary_path }} - LICENSE_PATH: ${{ steps.stage.outputs.license_path }} - run: | - set -euo pipefail - python .github/workflows/scripts/normalise_windows_paths.py - - id: package - name: Build Windows installer package - uses: >- - leynos/shared-actions/.github/actions/windows-package@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b - with: - product-name: ${{ needs.metadata.outputs.bin_name }} - manufacturer: Leynos - install-dir-name: ${{ needs.metadata.outputs.bin_name }} - application-path: >- - ${{ steps.normalize_windows_paths.outputs.binary_path }} - license-rtf-path: >- - ${{ steps.normalize_windows_paths.outputs.license_path }} - architecture: ${{ matrix.msi_arch }} - version: ${{ needs.metadata.outputs.version }} - output-basename: ${{ needs.metadata.outputs.bin_name }} - output-directory: dist - license-plaintext-path: LICENSE - upload-artifact: ${{ fromJSON(needs.metadata.outputs.should_publish) }} - wix-extension-version: ${{ needs.metadata.outputs.wix_extension_version }} - - name: Upload Windows artefacts - if: needs.metadata.outputs.should_publish == 'true' - uses: >- - actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - # v4 - with: - name: ${{ env.REPO_NAME }}-windows-${{ matrix.package_arch }} - path: | - ${{ steps.stage.outputs.artifact_dir }} - ${{ steps.package.outputs.msi-path }} + uses: ./.github/workflows/build-and-package.yml + with: + platform: windows + runner: windows-latest + target: ${{ matrix.target }} + artifact_label: windows-${{ matrix.package_arch }} + package_arch: ${{ matrix.package_arch }} + target_key: ${{ matrix.target_key }} + msi_arch: ${{ matrix.msi_arch }} + repo_name: ${{ env.REPO_NAME }} + bin_name: ${{ needs.metadata.outputs.bin_name }} + version: ${{ needs.metadata.outputs.version }} + should_publish: ${{ fromJSON(needs.metadata.outputs.should_publish) }} + wix_extension_version: ${{ needs.metadata.outputs.wix_extension_version }} build-macos: needs: metadata @@ -254,64 +178,18 @@ jobs: artifact_suffix: macos-arm64 package_arch: arm64 target_key: macos-aarch64 - runs-on: ${{ matrix.runner }} - steps: - - uses: >- - actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 - # v4.1.2 - - name: Install uv - uses: >- - astral-sh/setup-uv@4cda7d73322c50eac316ad623a716f09a2db2ac7 - # v3.1.2 - with: - python-version: '3.11' - - name: Build macOS release - uses: >- - leynos/shared-actions/.github/actions/rust-build-release@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b - with: - target: ${{ matrix.target }} - bin-name: ${{ needs.metadata.outputs.bin_name }} - version: ${{ needs.metadata.outputs.version }} - - id: stage - name: Stage macOS artefacts - uses: ./.github/actions/stage - with: - config-file: .github/release-staging.toml - target: ${{ matrix.target_key }} - - id: pkg - name: Build macOS installer package - uses: >- - leynos/shared-actions/.github/actions/macos-package@dd56f18c39f1e158eb04cd5b4fc9194aadb6b52b - with: - name: ${{ needs.metadata.outputs.bin_name }} - identifier: com.leynos.${{ needs.metadata.outputs.bin_name }} - binary: ${{ steps.stage.outputs.binary_path }} - manpage: ${{ steps.stage.outputs.man_path }} - license-file: LICENSE - version: ${{ needs.metadata.outputs.version }} - - name: Stamp architecture into package name - shell: bash - env: - BIN_NAME: ${{ needs.metadata.outputs.bin_name }} - VERSION: ${{ needs.metadata.outputs.version }} - ARCHIVE_SUFFIX: ${{ matrix.artifact_suffix }} - PKG_PATH: ${{ steps.pkg.outputs.pkg-path }} - run: | - set -euo pipefail - dest="dist/${BIN_NAME}-${VERSION}-${ARCHIVE_SUFFIX}.pkg" - mkdir -p "$(dirname "$dest")" - mv "$PKG_PATH" "$dest" - - name: Upload macOS artefacts - uses: >- - actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - # v4 - with: - name: ${{ env.REPO_NAME }}-${{ matrix.artifact_suffix }} - path: | - ${{ steps.stage.outputs.artifact_dir }} - dist/${{ needs.metadata.outputs.bin_name }}-${{ - needs.metadata.outputs.version }}-${{ - matrix.artifact_suffix }}.pkg + uses: ./.github/workflows/build-and-package.yml + with: + platform: macos + runner: ${{ matrix.runner }} + target: ${{ matrix.target }} + artifact_label: ${{ matrix.artifact_suffix }} + package_arch: ${{ matrix.package_arch }} + target_key: ${{ matrix.target_key }} + repo_name: ${{ env.REPO_NAME }} + bin_name: ${{ needs.metadata.outputs.bin_name }} + version: ${{ needs.metadata.outputs.version }} + should_publish: ${{ fromJSON(needs.metadata.outputs.should_publish) }} release: if: needs.metadata.outputs.should_publish == 'true'