diff --git a/.github/actions/build_cli/action.yml b/.github/actions/build_cli/action.yml new file mode 100644 index 0000000000..5743152707 --- /dev/null +++ b/.github/actions/build_cli/action.yml @@ -0,0 +1,20 @@ +name: build CLI +description: Build the Contrast CLI release binary for a given system + +inputs: + system: + description: Nix system (e.g. x86_64-linux, aarch64-darwin) + required: true + +runs: + using: "composite" + steps: + - name: Build CLI + shell: bash + env: + SET: base + SYSTEM: ${{ inputs.system }} + run: | + mkdir -p workspace + nix build -L ".#${SET}.contrast.cli-release" + cp result/bin/contrast "workspace/contrast-${SYSTEM}" diff --git a/.github/actions/release_artifacts/action.yml b/.github/actions/release_artifacts/action.yml index e2b5c48184..0a06a77816 100644 --- a/.github/actions/release_artifacts/action.yml +++ b/.github/actions/release_artifacts/action.yml @@ -113,7 +113,7 @@ runs: run: | cat << 'EOF' | tee -a "${GITHUB_OUTPUT}" paths< workspace/node-installer-target-config-k3s.yml - - name: Build CLI - shell: bash - env: - SET: base - run: | - nix build -L ".#${SET}.contrast.cli-release" --out-link workspace/contrast-cli - - name: AWS login (IAM role) - uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0 + - uses: ./.github/actions/build_cli with: - role-to-assume: arn:aws:iam::795746500882:role/ContrastPublicBucketRW - aws-region: eu-central-1 - - name: Upload pre-release artifacts to S3 bucket contrast-public + system: x86_64-linux + - id: upload-artifacts + uses: ./.github/actions/s3_upload if: ${{ inputs.s3-bucket-path != '' }} - id: upload-artifacts - shell: bash - env: - S3_BUCKET_PATH: ${{ inputs.s3-bucket-path }} - FILES: ${{ steps.artifact-paths.outputs.paths }} - run: | - set -u - shopt -s nullglob - unix=$(date +%s) - readarray -t patterns <<< "$FILES" - for pattern in "${patterns[@]}"; do - matches=($pattern) - for file in "${matches[@]}"; do - aws s3 cp "$file" "s3://contrast-public/${S3_BUCKET_PATH}/$unix/" - done - done - url="https://contrast-public.s3.eu-central-1.amazonaws.com/${S3_BUCKET_PATH}/$unix/" - echo "Artifacts available at $url" | tee -a "$GITHUB_STEP_SUMMARY" - echo "url=$url" | tee -a "$GITHUB_OUTPUT" + with: + files: ${{ steps.artifact-paths.outputs.paths }} + s3-bucket-path: ${{ inputs.s3-bucket-path }}/${{ github.run_id }}/${{ github.run_attempt }} diff --git a/.github/actions/s3_upload/action.yml b/.github/actions/s3_upload/action.yml new file mode 100644 index 0000000000..6f4e87554f --- /dev/null +++ b/.github/actions/s3_upload/action.yml @@ -0,0 +1,40 @@ +name: upload to S3 +description: Upload files to the contrast-public S3 bucket (assumes role via OIDC) + +inputs: + files: + description: Newline-separated list of files or glob patterns to upload + required: true + s3-bucket-path: + description: S3 key prefix (under the contrast-public bucket) + required: true + +outputs: + url: + description: Public URL of the uploaded artifacts + value: ${{ steps.upload-artifacts.outputs.url }} + +runs: + using: "composite" + steps: + - name: AWS login (IAM role) + uses: aws-actions/configure-aws-credentials@ec61189d14ec14c8efccab744f656cffd0e33f37 # v6.1.0 + with: + role-to-assume: arn:aws:iam::795746500882:role/ContrastPublicBucketRW + aws-region: eu-central-1 + - name: Upload pre-release artifacts to S3 bucket contrast-public + id: upload-artifacts + shell: bash + env: + S3_BUCKET_PATH: ${{ inputs.s3-bucket-path }} + FILES: ${{ inputs.files }} + run: | + shopt -s nullglob + while IFS= read -r pattern; do + for file in $pattern; do + aws s3 cp "$file" "s3://contrast-public/${S3_BUCKET_PATH}/" + done + done <<< "$FILES" + url="https://contrast-public.s3.eu-central-1.amazonaws.com/${S3_BUCKET_PATH}/" + echo "Artifacts available at $url" | tee -a "$GITHUB_STEP_SUMMARY" + echo "url=$url" | tee -a "$GITHUB_OUTPUT" diff --git a/.github/workflows/pr_release_artifacts.yml b/.github/workflows/pr_release_artifacts.yml index e9651c7ace..cc0aa659a9 100644 --- a/.github/workflows/pr_release_artifacts.yml +++ b/.github/workflows/pr_release_artifacts.yml @@ -17,11 +17,11 @@ jobs: if: github.event_name == 'workflow_dispatch' && github.event.inputs.cleanup == 'false' runs-on: ubuntu-24.04 permissions: - pull-requests: write - issues: write contents: read packages: write id-token: write + outputs: + s3-bucket-url: ${{ steps.create-artifacts.outputs.s3-bucket-url }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -51,6 +51,42 @@ jobs: version: ${{ steps.get-version.outputs.version }} container_registry: ghcr.io/edgelesssys s3-bucket-path: "pr-artifacts" + + build-darwin-cli: + name: Build aarch64-darwin CLI for PR + if: github.event_name == 'workflow_dispatch' && github.event.inputs.cleanup == 'false' + needs: [create-release-artifacts] + runs-on: macos-latest + permissions: + contents: read + id-token: write + env: + SET: base + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: ./.github/actions/setup_nix + with: + githubToken: ${{ secrets.GITHUB_TOKEN }} + cachixToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + - uses: ./.github/actions/build_cli + with: + system: aarch64-darwin + - uses: ./.github/actions/s3_upload + with: + files: workspace/contrast-aarch64-darwin + s3-bucket-path: pr-artifacts/${{ github.run_id }}/${{ github.run_attempt }} + + notify: + name: Create PR comment with artifact links + if: github.event_name == 'workflow_dispatch' && github.event.inputs.cleanup == 'false' + needs: [create-release-artifacts, build-darwin-cli] + runs-on: ubuntu-24.04 + permissions: + pull-requests: write + issues: write + steps: - name: Get PR number id: get-pr-number env: @@ -75,7 +111,7 @@ jobs: The pre-release artifacts for this commit are available at the following link: - ${{ steps.create-artifacts.outputs.s3-bucket-url }} + ${{ needs.create-release-artifacts.outputs.s3-bucket-url }} Created by @${{ github.actor }} in [pr_release_artifacts workflow]( https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}?pr=${{ steps.get-pr-number.outputs.pr_number }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2bf9222380..988dd19274 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -121,7 +121,7 @@ jobs: update-main: name: Update main branch runs-on: ubuntu-24.04 - needs: [process-inputs, release] + needs: [process-inputs, release-x86_64-linux, release-aarch64-darwin] permissions: contents: write env: @@ -182,6 +182,11 @@ jobs: with: name: contrast-release-artifacts path: ./contrast-main + - name: Download darwin CLI artifact + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: contrast-cli-aarch64-darwin + path: ./contrast-main/workspace - name: Update contrast-releases.json with new release working-directory: contrast-main run: nix run ".#${SET}.scripts.update-contrast-releases" @@ -217,7 +222,56 @@ jobs: token: ${{ secrets.NUNKI_CI_COMMIT_PUSH_PR }} path: ./contrast-main - release: + release-aarch64-darwin: + name: Build aarch64-darwin CLI + runs-on: macos-latest + needs: [process-inputs, release-x86_64-linux] + permissions: + contents: write + id-token: write + env: + VERSION: ${{ inputs.version }} + SET: base + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ needs.process-inputs.outputs.WORKING_BRANCH }} + persist-credentials: false + - uses: ./.github/actions/setup_nix + with: + githubToken: ${{ secrets.GITHUB_TOKEN }} + cachixToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + - name: Bump flake version to release version + uses: ./.github/actions/bump_version + with: + version: ${{ needs.process-inputs.outputs.WITHOUT_V }} + commit: false + - uses: ./.github/actions/build_cli + with: + system: aarch64-darwin + - name: Upload artifact + uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + with: + name: contrast-cli-aarch64-darwin + path: workspace/contrast-aarch64-darwin + - name: Remove existing darwin asset from draft release + env: + GH_TOKEN: ${{ github.token }} + run: | + if gh release view "${VERSION}" --repo "${{ github.repository }}" --json assets --jq '.assets[].name' | grep -Fxq 'contrast-aarch64-darwin'; then + gh release delete-asset "${VERSION}" contrast-aarch64-darwin --repo "${{ github.repository }}" --yes + fi + - name: Attach to release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release upload "${VERSION}" workspace/contrast-aarch64-darwin --repo "${{ github.repository }}" + - uses: ./.github/actions/s3_upload + with: + files: workspace/contrast-aarch64-darwin + s3-bucket-path: pre-releases/${{ inputs.version }}/${{ github.run_id }}/${{ github.run_attempt }} + + release-x86_64-linux: name: Build and push artifacts, create release runs-on: ubuntu-24.04 needs: process-inputs @@ -315,7 +369,7 @@ jobs: # Job needs content:write to see draft releases. contents: write packages: read - needs: [process-inputs, release, nightly] + needs: [process-inputs, release-x86_64-linux, nightly] env: VERSION: ${{ inputs.version }} SET: base @@ -387,7 +441,7 @@ jobs: nightly: name: e2e nightly - needs: release + needs: release-x86_64-linux uses: ./.github/workflows/e2e_nightly.yml secrets: GITHUB_TOKEN_IN: ${{ secrets.GITHUB_TOKEN }} @@ -401,7 +455,7 @@ jobs: publish: name: Publish release - needs: [process-inputs, release, test] + needs: [process-inputs, release-x86_64-linux, release-aarch64-darwin, test] runs-on: ubuntu-24.04 environment: release-publish permissions: diff --git a/docs/docs/howto/install-cli.md b/docs/docs/howto/install-cli.md index 406590b2f0..63077adb31 100644 --- a/docs/docs/howto/install-cli.md +++ b/docs/docs/howto/install-cli.md @@ -12,14 +12,33 @@ Required for deploying with Contrast. ## How-to -Download the Contrast CLI from the latest release: +Download the Contrast CLI from the latest release and install it in your PATH: + + + ```bash -curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/latest/download/contrast +curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/latest/download/contrast-x86_64-linux +sudo install contrast /usr/local/bin/contrast ``` -After that, install the Contrast CLI in your PATH, e.g.: + + ```bash +curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/latest/download/contrast-aarch64-darwin sudo install contrast /usr/local/bin/contrast ``` + +:::note +If you download the binary via a web browser instead of `curl`, macOS may show a warning +that the software can't be verified. Remove the quarantine attribute before installing the binary: + +```bash +sudo xattr -d com.apple.quarantine contrast +``` + +::: + + + diff --git a/packages/update-contrast-releases.sh b/packages/update-contrast-releases.sh index e3dfdb300d..c866c6f7b5 100755 --- a/packages/update-contrast-releases.sh +++ b/packages/update-contrast-releases.sh @@ -31,7 +31,8 @@ target_configs=( # declare an associative array that pairs the field name # in ./packages/versions.json with the path to the file declare -A fields -fields["contrast"]="./workspace/contrast-cli/bin/contrast" +fields["contrast"]="./workspace/contrast-x86_64-linux" +fields["contrast-aarch64-darwin"]="./workspace/contrast-aarch64-darwin" fields["coordinator.yml"]="./workspace/coordinator.yml" fields["runtime.yml"]="./workspace/runtime.yml" fields["emojivoto-demo.zip"]="./workspace/emojivoto-demo.zip"