| # The way this works is the following: | |
| # | |
| # The create-release job runs purely to initialize the GitHub release itself | |
| # and to output upload_url for the following job. | |
| # | |
| # The build-release job runs only once create-release is finished. It gets the | |
| # release upload URL from create-release job outputs, then builds the release | |
| # executables for each supported platform and attaches them as release assets | |
| # to the previously created release. | |
| # | |
| # The key here is that we create the release only once. | |
| # | |
| # Reference: | |
| # https://eugene-babichenko.github.io/blog/2020/05/09/github-actions-cross-platform-auto-releases/ | |
| name: release-agent | |
| on: | |
| push: | |
| # Enable when testing release infrastructure on a branch. | |
| # branches: | |
| # - test | |
| tags: | |
| - "agent-[0-9]+.[0-9]+.[0-9]+" | |
| jobs: | |
| create-release: | |
| name: create-release | |
| runs-on: ubuntu-latest | |
| # env: | |
| # Set to force version number, e.g., when no tag exists. | |
| # AGENT_VERSION: TEST-0.0.0 | |
| outputs: | |
| upload_url: ${{ steps.release.outputs.upload_url }} | |
| agent_version: ${{ env.AGENT_VERSION }} | |
| steps: | |
| - name: Get the release version from the tag | |
| shell: bash | |
| if: env.AGENT_VERSION == '' | |
| run: | | |
| # Apparently, this is the right way to get a tag name. Really? | |
| # | |
| # See: https://github.community/t5/GitHub-Actions/How-to-get-just-the-tag-name/m-p/32167/highlight/true#M1027 | |
| echo "AGENT_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV | |
| echo "version is: ${{ env.AGENT_VERSION }}" | |
| - name: Create GitHub release | |
| id: release | |
| uses: actions/create-release@v1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: ${{ env.AGENT_VERSION }} | |
| release_name: ${{ env.AGENT_VERSION }} | |
| build-release: | |
| name: build-release | |
| needs: ['create-release'] | |
| runs-on: ${{ matrix.os }} | |
| env: | |
| # Emit backtraces on panics. | |
| RUST_BACKTRACE: 1 | |
| strategy: | |
| matrix: | |
| build: [linux, linux-aarch64, macos-intel, macos-m1, win-msvc] | |
| include: | |
| - build: linux | |
| os: ubuntu-latest | |
| rust: nightly | |
| target: x86_64-unknown-linux-musl | |
| - build: linux-aarch64 | |
| os: ubuntu-latest | |
| rust: nightly | |
| target: aarch64-unknown-linux-musl # cross compile to aarch64 on x86_64 | |
| - build: macos-intel | |
| os: macos-latest | |
| rust: nightly | |
| target: x86_64-apple-darwin | |
| - build: macos-m1 | |
| os: macos-latest | |
| rust: nightly | |
| target: aarch64-apple-darwin # cross compile to aarch64 on x86_64 | |
| - build: win-msvc | |
| os: windows-latest | |
| rust: nightly | |
| target: x86_64-pc-windows-msvc | |
| steps: | |
| - name: Install deps (linux-aarch64) | |
| if: matrix.build == 'linux-aarch64' | |
| run: sudo apt-get install -y wget && cd /opt && wget http://musl.cc/aarch64-linux-musl-cross.tgz && tar xf aarch64-linux-musl-cross.tgz | |
| - name: Install deps (linux) | |
| if: matrix.build == 'linux' | |
| run: sudo apt-get install -y musl-tools | |
| - name: Checkout repository | |
| uses: actions/checkout@v2 | |
| with: | |
| fetch-depth: 1 | |
| - name: Install Rust | |
| uses: actions-rs/toolchain@v1 | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| profile: minimal | |
| override: true | |
| target: ${{ matrix.target }} | |
| - name: Test release binary | |
| if: matrix.build != 'macos-m1' && matrix.build != 'linux-aarch64' # Can't run aarch64 binary on x86_64 | |
| working-directory: agent | |
| run: cargo test --verbose --release --target ${{ matrix.target }} | |
| - name: Build release binary | |
| if: matrix.build != 'linux-aarch64' | |
| working-directory: agent | |
| run: cargo build --verbose --release --target ${{ matrix.target }} | |
| - name: Build release binary (linux-aarch64) | |
| if: matrix.build == 'linux-aarch64' | |
| working-directory: agent | |
| run: CC=/opt/aarch64-linux-musl-cross/bin/aarch64-linux-musl-gcc cargo build --verbose --release --target ${{ matrix.target }} --config target.${{ matrix.target }}.linker=\"/opt/aarch64-linux-musl-cross/bin/aarch64-linux-musl-ld\" | |
| - name: Strip release binary (linux and macos) | |
| if: matrix.build == 'linux' || matrix.build == 'macos-intel' || matrix.build == 'macos-m1' | |
| working-directory: agent | |
| run: strip "target/${{ matrix.target }}/release/bazelci-agent" | |
| - name: Strip release binary (linux-aarch64) | |
| if: matrix.build == 'linux-aarch64' | |
| working-directory: agent | |
| run: /opt/aarch64-linux-musl-cross/bin/aarch64-linux-musl-strip "target/${{ matrix.target }}/release/bazelci-agent" | |
| - name: Build release asset | |
| shell: bash | |
| run: | | |
| staging="bazelci-${{ needs.create-release.outputs.agent_version }}-${{ matrix.target }}" | |
| if [ "${{ matrix.os }}" = "windows-latest" ]; then | |
| cp "agent/target/${{ matrix.target }}/release/bazelci-agent.exe" "$staging.exe" | |
| echo "ASSET=$staging.exe" >> $GITHUB_ENV | |
| else | |
| cp "agent/target/${{ matrix.target }}/release/bazelci-agent" "$staging" | |
| echo "ASSET=$staging" >> $GITHUB_ENV | |
| fi | |
| - name: Upload release asset | |
| uses: actions/upload-release-asset@v1.0.1 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| upload_url: ${{ needs.create-release.outputs.upload_url }} | |
| asset_path: ${{ env.ASSET }} | |
| asset_name: ${{ env.ASSET }} | |
| asset_content_type: application/octet-stream |