chore: next round of ci enhancements/fixes #90
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
| # | ||
| # Copyright (c) 2024 Elide Technologies, Inc. | ||
| # | ||
| # Licensed under the MIT license (the "License"); you may not use this file except in compliance | ||
| # with the License. You may obtain a copy of the License at | ||
| # | ||
| # https://opensource.org/license/mit/ | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
| # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| # License for the specific language governing permissions and limitations under the License. | ||
| # | ||
| name: Native Image | ||
| "on": | ||
| workflow_dispatch: | ||
| inputs: | ||
| ## Input: Enable Release Targets | ||
| release: | ||
| description: "Release" | ||
| type: boolean | ||
| default: false | ||
| ## Input: Enable Signing | ||
| signing: | ||
| description: "Signing" | ||
| type: boolean | ||
| default: false | ||
| ## Input: Enable Provenance | ||
| provenance: | ||
| description: "Provenance" | ||
| type: boolean | ||
| default: false | ||
| ## Input: Static Linkage | ||
| static: | ||
| description: "Static" | ||
| type: boolean | ||
| default: false | ||
| ## Input: Runner | ||
| runner: | ||
| description: "Runner" | ||
| type: string | ||
| default: ubuntu-cipool | ||
| ## Input: Architecture | ||
| arch: | ||
| description: "Architecture Tag" | ||
| type: choice | ||
| options: | ||
| - "amd64" | ||
| - "arm64" | ||
| - "aarch64" | ||
| default: amd64 | ||
| ## Input: Operating System | ||
| os: | ||
| description: "OS Tag" | ||
| type: choice | ||
| options: | ||
| - "linux" | ||
| - "darwin" | ||
| - "windows" | ||
| default: "linux" | ||
| ## Input: Optimization | ||
| opt: | ||
| description: "Optimization" | ||
| type: choice | ||
| options: | ||
| - "0" | ||
| - "1" | ||
| - "2" | ||
| - "3" | ||
| - "4" | ||
| - "b" | ||
| - "s" | ||
| default: "4" | ||
| ## Input: PGO | ||
| pgo: | ||
| description: "PGO" | ||
| type: boolean | ||
| default: false | ||
| ## Input: Release Packing | ||
| pack: | ||
| description: "Pack" | ||
| type: boolean | ||
| default: false | ||
| ## Input: Version Override | ||
| version: | ||
| description: "Version Override" | ||
| type: string | ||
| default: "" | ||
| workflow_call: | ||
| inputs: | ||
| release: | ||
| description: "Release" | ||
| type: boolean | ||
| default: false | ||
| signing: | ||
| description: "Signing" | ||
| type: boolean | ||
| default: false | ||
| provenance: | ||
| description: "Provenance" | ||
| type: boolean | ||
| default: false | ||
| static: | ||
| description: "Static" | ||
| type: boolean | ||
| default: false | ||
| runner: | ||
| description: "Runner" | ||
| type: string | ||
| default: ubuntu-cipool | ||
| arch: | ||
| description: "Architecture Tag" | ||
| type: string | ||
| default: amd64 | ||
| os: | ||
| description: "OS Tag" | ||
| type: string | ||
| default: linux | ||
| opt: | ||
| description: "Optimization" | ||
| type: string | ||
| default: "4" | ||
| pgo: | ||
| description: "PGO" | ||
| type: boolean | ||
| default: false | ||
| pack: | ||
| description: "Pack" | ||
| type: boolean | ||
| default: false | ||
| version: | ||
| description: "Version Override" | ||
| type: string | ||
| default: "" | ||
| outputs: | ||
| hashes: | ||
| description: "Provenance Hashes" | ||
| value: ${{ jobs.gradle.outputs.hashes }} | ||
| version: | ||
| description: "Release Version" | ||
| value: ${{ jobs.gradle.outputs.version }} | ||
| secrets: | ||
| BUILDLESS_APIKEY: | ||
| required: false | ||
| description: "Buildless API Key" | ||
| BUILDBOT_SERVICE_ACCOUNT: | ||
| required: false | ||
| description: "GCP Service Account" | ||
| BUILDBOT_GHCR_TOKEN: | ||
| required: false | ||
| description: "GHCR Token" | ||
| CODECOV_TOKEN: | ||
| required: false | ||
| description: "Codecov token" | ||
| GRADLE_CONFIGURATION_KEY: | ||
| required: false | ||
| description: "Gradle cache key" | ||
| COSIGN_KEY: | ||
| required: false | ||
| description: "Cosign Key" | ||
| COSIGN_PASSWORD: | ||
| required: false | ||
| description: "Cosign Password" | ||
| SIGNING_KEY: | ||
| required: true | ||
| description: "GPG Signing Key" | ||
| # Do not add `ELIDE_VERSION` here like other workflows, or it may interfere with the release version override. | ||
| env: | ||
| RUST_BACKTRACE: full | ||
| BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }} | ||
| MACOSX_DEPLOYMENT_TARGET: "14.0" | ||
| permissions: | ||
| contents: read | ||
| jobs: | ||
| ## | ||
| ## Job: Library Build | ||
| ## | ||
| gradle: | ||
| name: "Native (${{ inputs.os }}-${{ inputs.arch }})" | ||
| runs-on: ${{ inputs.runner }} | ||
| permissions: | ||
| contents: write | ||
| id-token: write | ||
| defaults: | ||
| run: | ||
| shell: bash | ||
| outputs: | ||
| hashes: ${{ steps.hash.outputs.hashes }} | ||
| version: ${{ steps.release-prep.outputs.version }} | ||
| platform: ${{ inputs.os }}-${{ inputs.arch }} | ||
| releaseArtifact: ${{ steps.pack-artifact.outputs.id }} | ||
| builtArtifact: ${{ steps.build-artifact.outputs.id }} | ||
| steps: | ||
| - name: "Setup: Harden Runner" | ||
| uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0 | ||
| with: | ||
| disable-sudo: false | ||
| egress-policy: audit | ||
| - name: "Setup: Checkout" | ||
| uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | ||
| with: | ||
| fetch-depth: 1 | ||
| submodules: true | ||
| persist-credentials: false | ||
| clean: true | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: "Setup: Packages" | ||
| if: contains(inputs.runner, 'ubuntu') || contains(inputs.runner, 'linux') | ||
| run: sudo apt-get update && sudo apt-get install -y build-essential libssl-dev libtool libtool-bin | ||
| - name: "Setup: Rust" | ||
| uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 # v1.13.0 | ||
| with: | ||
| toolchain: stable | ||
| cache: false # handled by sccache | ||
| - name: "Setup: SCCache" | ||
| uses: mozilla-actions/sccache-action@7d986dd989559c6ecdb630a3fd2557667be217ad # v0.0.9 | ||
| - name: "Setup: Rust Caching" | ||
| run: echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV | ||
| - name: "Setup: GraalVM (Java 25)" | ||
| uses: graalvm/setup-graalvm@eec48106e0bf45f2976c2ff0c3e22395cced8243 # v1.4.2 | ||
| with: | ||
| distribution: "graalvm" | ||
| java-version: "25" | ||
| github-token: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: "Setup: PNPM" | ||
| uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 | ||
| with: | ||
| version: "10.6.2" | ||
| - name: "Setup: Node" | ||
| uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 | ||
| with: | ||
| node-version: 23 | ||
| - name: "Setup: Bun" | ||
| uses: step-security/setup-bun@81c6b5758214d7e8b68a403c6a55a040e9b8879a # v2.0.3 | ||
| with: | ||
| bun-version: "1.2.14" | ||
| - name: "Setup: uv" | ||
| uses: astral-sh/setup-uv@85856786d1ce8acfbcc2f13a5f3fbd6b938f9f41 # v7.1.2 | ||
| - name: "Setup: Dependencies" | ||
| run: | | ||
| echo "Setting up venv..." | ||
| uv venv | ||
| echo "Activating venv..." | ||
| . .venv/bin/activate | ||
| echo "Installing dependencies via Pip..." | ||
| uv pip install -r config/requirements.txt | ||
| echo PATH=$PATH >> $GITHUB_ENV | ||
| echo "Installing dependencies..." | ||
| pnpm install | ||
| - name: "Setup: Gradle" | ||
| uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # v5.0.0 | ||
| id: gradlebuild | ||
| env: | ||
| CI: true | ||
| BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }} | ||
| cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} | ||
| with: | ||
| cache-read-only: true | ||
| cache-encryption-key: ${{ secrets.GRADLE_CONFIGURATION_KEY }} | ||
| dependency-graph: disabled | ||
| gradle-home-cache-cleanup: true | ||
| gradle-home-cache-includes: binaryen | ||
| caches | ||
| jdks | ||
| native | ||
| native-build-tools | ||
| nodejs | ||
| notifications | ||
| wrapper | ||
| yarn | ||
| - name: "Setup: Gradle Settings" | ||
| run: cp -fv ./.github/workflows/gradle-ci.properties ~/.gradle/gradle.properties | ||
| - name: "Setup: Gradle Settings (Globals)" | ||
| run: cp -fv /home/ci-agent/gradle-ci.properties ~/.gradle/gradle.properties || echo "No global settings." | ||
| - name: "Setup: Cosign" | ||
| if: inputs.pack | ||
| uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 # v3.10.0 | ||
| - name: "Build Environment" | ||
| run: file Makefile && make info CI=yes 2>&1 | tee build-info.txt | ||
| - name: "Overrides: Version" | ||
| if: inputs.version != '' | ||
| run: | | ||
| current_version=$(cat ./.version) | ||
| echo "${{ inputs.version }}" > ./.version | ||
| echo "${{ inputs.version }}" > ./.release | ||
| sed -i "s/elide = \"${current_version}\"/elide = \"${{ inputs.version }}\"/g" gradle/elide.versions.toml | ||
| sed -i "s/elide-bin = \"${current_version}\"/elide-bin = \"${{ inputs.version }}\"/g" gradle/elide.versions.toml | ||
| sed -i "s/${current_version}/${{ inputs.version }}/g" tools/elide-build/src/main/kotlin/elide/internal/conventions/Constants.kt | ||
| - name: "🛠️ Release: Third-Party Natives" | ||
| env: | ||
| CI: true | ||
| BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }} | ||
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | ||
| TEST_EXCEPTIONS: true | ||
| run: make -C third_party CI=yes -j2 | ||
| timeout-minutes: 5 | ||
| - name: "🛠️ Release: Image" | ||
| env: | ||
| CI: true | ||
| BUILDLESS_APIKEY: ${{ secrets.BUILDLESS_APIKEY }} | ||
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | ||
| TEST_EXCEPTIONS: true | ||
| timeout-minutes: 30 | ||
| run: | | ||
| ./gradlew \ | ||
| :packages:cli:nativeOptimizedCompile \ | ||
| -x check \ | ||
| -x test \ | ||
| -x jvmTest \ | ||
| --scan \ | ||
| --build-cache \ | ||
| --daemon \ | ||
| --dependency-verification=off \ | ||
| --no-configuration-cache \ | ||
| --stacktrace \ | ||
| -Pelide.ci=true \ | ||
| -PbuildSamples=false \ | ||
| -PbuildDocs=false \ | ||
| -Pelide.optMode=${{ inputs.opt }} \ | ||
| -Pelide.stamp=${{ inputs.release }} \ | ||
| -Pelide.pgo=${{ inputs.pgo }} \ | ||
| -Pelide.static=${{ inputs.static == true && 'true' || 'false' }} \ | ||
| -Pelide.release=${{ inputs.release }} \ | ||
| -Pelide.buildMode=${{ inputs.release == true && 'release' || 'dev' }} | ||
| - name: "Setup: Signing Keys" | ||
| if: inputs.release && inputs.pack && inputs.signing | ||
| run: | | ||
| cat <(echo -e "${{ secrets.SIGNING_KEY }}") | base64 -d | gpg --batch --import | ||
| gpg --list-secret-keys --keyid-format LONG | ||
| mkdir -p /home/$(whoami)/.gnupg/ | ||
| gpg --export-secret-keys > /home/$(whoami)/.gnupg/secring.gpg || echo "No key exported." | ||
| - name: "Artifact: Build Outputs" | ||
| uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 | ||
| id: build-artifact | ||
| with: | ||
| name: elide-native-${{ inputs.release == true && 'release' || 'dev' }}-${{ inputs.os }}-${{ inputs.arch }} | ||
| path: packages/cli/build/native/nativeOptimizedCompile/**/*.* | ||
| - name: "Artifact: Provenance Subject" | ||
| id: hash | ||
| if: inputs.release && inputs.pack && inputs.provenance | ||
| run: | | ||
| echo "hashes=$(sha256sum ./packages/cli/build/native/nativeOptimizedCompile/elide | base64 -w0)" >> "$GITHUB_OUTPUT" | ||
| - name: "🛠️ Release: Package" | ||
| if: inputs.pack | ||
| run: bash ./tools/scripts/release/build-release.sh | ||
| env: | ||
| COSIGN_KEY: ${{ secrets.COSIGN_KEY }} | ||
| COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }} | ||
| COSIGN_ARGS: "--key env://COSIGN_KEY" | ||
| - name: "Release: Prepare" | ||
| if: inputs.pack | ||
| id: release-prep | ||
| run: | | ||
| currentVersion=$(cat ./.release) | ||
| releaseOverride="${{ inputs.version }}" | ||
| version="${releaseOverride:-$currentVersion}" | ||
| cd ./packages/cli/build/native/nativeOptimizedCompile/; | ||
| mkdir -p "release/${{ inputs.os }}-${{ inputs.arch }}/$version" | ||
| cp -fv elide-*.{tgz,txz,zip}* "release/${{ inputs.os }}-${{ inputs.arch }}/$version/" | ||
| cp -fv elide.sbom.json "release/${{ inputs.os }}-${{ inputs.arch }}/$version/" | ||
| cp -fv elide-build-report.html "release/${{ inputs.os }}-${{ inputs.arch }}/$version/elide.build-report.html" | ||
| cd -; | ||
| mkdir -p staging/release | ||
| mv "packages/cli/build/native/nativeOptimizedCompile/release" "staging/" | ||
| echo "version=$version" >> $GITHUB_OUTPUT | ||
| tree -L 3 staging/ | ||
| echo "Release built." | ||
| - name: "Artifact: Release Package" | ||
| uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 | ||
| id: pack-artifact | ||
| if: inputs.pack | ||
| with: | ||
| name: elide-native-${{ inputs.release == true && 'release' || 'dev' }}-${{ inputs.os }}-${{ inputs.arch }}-release.zip | ||
| path: staging/**/*.* | ||