name: Release

on:
  workflow_dispatch:
    inputs:
      release_version:
        description: "Release version"
        required: true
        default: ""
      create_release:
        description: "Create release"
        required: true
        default: "true"
      upload_artifacts:
        description: "Upload artifacts"
        required: true
        default: "true"
      upload_url:
        description: "Upload URL"
        required: false
        default: ""
      base_hash:
          description: "Commit hash from which to build"
          required: false
          type: string
          default: ""
  push:
    tags:
    - "v*"

concurrency:
  group: release-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  RUST_BACKTRACE: 1
  RUSTFLAGS: -Dwarnings
  RUSTDOCFLAGS: -Dwarnings
  MSRV: "1.76"
  SCCACHE_CACHE_SIZE: "50G"
  BIN_NAMES: "iroh,iroh-relay,iroh-dns-server"
  RELEASE_VERSION: ${{ github.event.inputs.release_version }}

jobs:
    create-release:
      name: create-release
      runs-on: ubuntu-latest
      outputs:
        upload_url: ${{ steps.release.outputs.upload_url }}
        release_version: ${{ env.RELEASE_VERSION }}
      steps:
      - name: Get the release version from the tag or input
        shell: bash
        if: env.RELEASE_VERSION == ''
        run: |
          if "${{ github.event.inputs.release_version }}" != ""; then
            echo "RELEASE_VERSION=${{ github.event.inputs.release_version }}" >> $GITHUB_ENV
            echo "version is: ${{ env.RELEASE_VERSION }}"
          else
            # See: https://github.community/t5/GitHub-Actions/How-to-get-just-the-tag-name/m-p/32167/highlight/true#M1027
            echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
            echo "version is: ${{ env.RELEASE_VERSION }}"
          fi
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 1
      - name: Create GitHub release
        id: release
        if: github.event.inputs.create_release == 'true' || github.event_name == 'push'
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          draft: true
          tag_name: ${{ env.RELEASE_VERSION ||  github.event.inputs.release_version}}
          release_name: ${{ env.RELEASE_VERSION ||  github.event.inputs.release_version }}

    build_release:
        timeout-minutes: 60
        name: Build release binaries
        needs: create-release
        runs-on: ${{ matrix.runner }}
        outputs:
          release_version: ${{ needs.create-release.outputs.release_version }}
          base_hash: ${{ steps.define_hash.outputs.base_hash }}
        continue-on-error: false
        strategy:
          fail-fast: false
          matrix:
            name: [ubuntu-latest, ubuntu-arm-latest, macOS-latest, macOS-arm-latest, windows-latest]
            rust: [stable]
            experimental: [false]
            include:
              - name: ubuntu-arm-latest
                os: ubuntu-latest
                release-os: linux
                release-arch: aarch64
                cargo_targets: "aarch64-unknown-linux-musl"
                runner: [self-hosted, linux, ARM64]
              - name: ubuntu-latest
                os: ubuntu-latest
                release-os: linux
                release-arch: amd64
                cargo_targets: "x86_64-unknown-linux-musl"
                runner: [self-hosted, linux, X64]
              - name: macOS-latest
                os: macOS-latest
                release-os: darwin
                release-arch: x86_64
                cargo_targets: "x86_64-apple-darwin"
                runner: [self-hosted, macOS, ARM64]
              - name: macOS-arm-latest
                os: macOS-latest
                release-os: darwin
                release-arch: aarch64
                cargo_targets: "aarch64-apple-darwin"
                runner: [self-hosted, macOS, ARM64]
              - name: windows-latest
                os: windows-latest
                release-os: windows
                release-arch: amd64
                cargo_targets: "x86_64-pc-windows-msvc"
                runner: [self-hosted, windows, X64]
        env:
          # Using self-hosted runners so use local cache for sccache and
          # not SCCACHE_GHA_ENABLED.
          # RUSTC_WRAPPER: "sccache"
          RUST_BACKTRACE: full
          RUSTV: ${{ matrix.rust }}
        steps:
        - name: Checkout
          if: inputs.base_hash == ''
          uses: actions/checkout@v6
          with:
            submodules: recursive
        
        - name: Checkout specified commit
          if: inputs.base_hash != ''
          uses: actions/checkout@v6
          with:
            ref: ${{ inputs.base_hash }}
            submodules: recursive
    
        - name: Set build arch
          run: |
            echo "RELEASE_ARCH=${{ matrix.release-arch }}" >> $GITHUB_ENV
            echo "RELEASE_OS=${{ matrix.release-os }}" >> $GITHUB_ENV
        
        - name: Define hash
          if: matrix.os == 'ubuntu-latest'
          id: define_hash
          run: |
            echo "base_hash=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"

        - name: Ensure musl support
          if: ${{ contains(matrix.cargo_targets, '-musl') }}
          run: sudo apt-get install musl-tools -y
    
        - name: Install Rust
          if: matrix.os != 'windows-latest'
          uses: dtolnay/rust-toolchain@stable
          with:
            toolchain: ${{ matrix.rust }}
            targets: ${{ matrix.cargo_targets }}

        - name: Install Rust
          if: matrix.os == 'windows-latest'
          run: |
            rustup toolchain install stable
            rustup target add ${{ matrix.cargo_targets }}
    
        - name: build release
          if: matrix.os != 'windows-latest'
          shell: bash
          run: |
            if [ "${{ matrix.name }}" = "ubuntu-arm-latest" ]; then
              export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=aarch64-linux-gnu-gcc
              export CC=aarch64-linux-gnu-gcc
            fi
            cargo build --profile optimized-release --all-features --target ${{ matrix.cargo_targets }}
        
        - name: build release
          if: matrix.os == 'windows-latest'
          run: cargo build --profile optimized-release --all-features --target ${{ matrix.cargo_targets }}
            
        - name: attach artifacts
          if: matrix.os != 'windows-latest'
          uses: actions/upload-artifact@v6
          with:
            name: iroh-${{env.RELEASE_OS }}-${{env.RELEASE_ARCH}}
            path: target/${{ matrix.cargo_targets }}/optimized-release/iroh
            compression-level: 0
        
        - name: attach artifacts
          if: matrix.os == 'windows-latest'
          uses: actions/upload-artifact@v6
          with:
            name: iroh-windows-amd64.exe
            path: target/${{ matrix.cargo_targets }}/optimized-release/iroh.exe
            compression-level: 0
    
        - name: Setup awscli on linux
          if: matrix.name == 'ubuntu-latest'
          run: |
            curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
            unzip awscliv2.zip
            sudo ./aws/install --update
    
        - name: Setup awscli on linux
          if: matrix.name == 'ubuntu-arm-latest'
          run: |
            curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
            unzip awscliv2.zip
            sudo ./aws/install --update
    
        - name: Setup awscli on mac
          if: matrix.os == 'macos-latest'
          run: |
            curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
            sudo installer -pkg AWSCLIV2.pkg -target /
    
        - name: Set aws credentials
          if: matrix.os != 'windows-latest'
          run: |
              echo "AWS_ACCESS_KEY_ID=${{secrets.S3_ACCESS_KEY_ID}}" >> $GITHUB_ENV
              echo "AWS_SECRET_ACCESS_KEY=${{secrets.S3_ACCESS_KEY}}" >> $GITHUB_ENV
              echo "AWS_DEFAULT_REGION=us-west-2" >> $GITHUB_ENV
    
        - name: push release
          if: matrix.os != 'windows-latest'
          run: |
            aws s3 cp ./target/${{ matrix.cargo_targets }}/optimized-release/iroh s3://vorc/iroh-${RELEASE_OS}-${RELEASE_ARCH}-${GITHUB_SHA::7} --no-progress
            aws s3 cp ./target/${{ matrix.cargo_targets }}/optimized-release/iroh-relay s3://vorc/iroh-relay-${RELEASE_OS}-${RELEASE_ARCH}-${GITHUB_SHA::7} --no-progress
            aws s3 cp ./target/${{ matrix.cargo_targets }}/optimized-release/iroh-dns-server s3://vorc/iroh-dns-server-${RELEASE_OS}-${RELEASE_ARCH}-${GITHUB_SHA::7} --no-progress
    
        - name: push release latest
          if: matrix.os != 'windows-latest'
          run: |
            aws s3 cp ./target/${{ matrix.cargo_targets }}/optimized-release/iroh s3://vorc/iroh-${RELEASE_OS}-${RELEASE_ARCH}-latest --no-progress
            aws s3 cp ./target/${{ matrix.cargo_targets }}/optimized-release/iroh-relay s3://vorc/iroh-relay-${RELEASE_OS}-${RELEASE_ARCH}-latest --no-progress
            aws s3 cp ./target/${{ matrix.cargo_targets }}/optimized-release/iroh-dns-server s3://vorc/iroh-dns-server-${RELEASE_OS}-${RELEASE_ARCH}-latest --no-progress

        - name: Build archives
          if: matrix.os != 'windows-latest'
          shell: bash
          run: |
            IFS=',' read -ra BIN_NAMES <<< "${{ env.BIN_NAMES }}"
            ASSETS=""
            for BIN_NAME in "${BIN_NAMES[@]}"; do
              staging="$BIN_NAME-${{ needs.create-release.outputs.release_version }}-${{ matrix.cargo_targets }}"
              mkdir -p "$staging"
              cp "target/${{ matrix.cargo_targets }}/optimized-release/$BIN_NAME" "$staging/"
              tar czf "$staging.tar.gz" -C "$staging" .
              ASSETS+="$staging.tar.gz,"
            done
            echo "ASSET=$(echo $ASSETS | sed 's/,$//')" >> $GITHUB_ENV

        - name: Build archives (windows)
          if: matrix.os == 'windows-latest'
          shell: pwsh
          run: |
            $BIN_NAMES = "${{ env.BIN_NAMES }}".Split(',')
            $ASSETS = @()
            foreach ($BIN_NAME in $BIN_NAMES) {
              $staging = "$BIN_NAME-${{ needs.create-release.outputs.release_version }}-${{ matrix.cargo_targets }}"
              New-Item -ItemType Directory -Force -Path "$staging"
              Copy-Item -Path "target/${{ matrix.cargo_targets }}/optimized-release/$BIN_NAME.exe" -Destination "$staging/"
              Set-Location -Path "$staging"
              Compress-Archive -Path * -DestinationPath "../$staging.zip"
              $ASSETS += "$staging.zip"
              Set-Location -Path ..
            }
            $ASSETS = $ASSETS -join ','
            Add-Content -Path $env:GITHUB_ENV -Value "ASSET=$ASSETS"

        - uses: n0-computer/actions-upload-release-asset@main
          if: (github.event.inputs.upload_artifacts == 'true' || github.event_name == 'push')
          with:
            upload_url: ${{ github.event.inputs.upload_url || needs.create-release.outputs.upload_url }}
            asset_path: ${{ env.ASSET }}

        - name: attach artifacts
          uses: actions/upload-artifact@v6
          if : matrix.os != 'windows-latest'
          with:
            name: iroh-${{ matrix.release-os }}-${{ matrix.release-arch }}-bundle
            path: iroh-*.tar.gz
            compression-level: 0
            retention-days: 1
          
        - name: attach artifacts
          uses: actions/upload-artifact@v6
          if : matrix.os == 'windows-latest'
          with:
            name: iroh-${{ matrix.release-os }}-${{ matrix.release-arch }}-bundle
            path: iroh-*.zip
            compression-level: 0
            retention-days: 1

    docker:
      needs: build_release
      uses: './.github/workflows/docker.yaml'
      secrets: inherit
      with:
        release_version: ${{ needs.build_release.outputs.release_version }}
        base_hash: ${{ needs.build_release.outputs.base_hash }}
        publish: true

Homonyms

soft3/radio/.github/workflows/release.yml
soft3/radio/iroh-ffi/.github/workflows/release.yml
cyb/honeycrisp/aruminium/.github/workflows/release.yml
cyb/honeycrisp/rane/.github/workflows/release.yml
cyb/honeycrisp/.claude/worktrees/agent-ad6c77c38e86bc291/rane/.github/workflows/release.yml
cyb/honeycrisp/.claude/worktrees/agent-aa1259cb10112b22a/rane/.github/workflows/release.yml
cyb/honeycrisp/.claude/worktrees/agent-ad6c77c38e86bc291/aruminium/.github/workflows/release.yml
cyb/honeycrisp/.claude/worktrees/agent-aa1259cb10112b22a/aruminium/.github/workflows/release.yml

Graph