diff --git a/.github/workflows/build-and-integration-tests.yml b/.github/workflows/build-and-integration-tests.yml deleted file mode 100644 index 3b7c78db..00000000 --- a/.github/workflows/build-and-integration-tests.yml +++ /dev/null @@ -1,215 +0,0 @@ -name: Build and integration tests - -on: - push: - branches: [ main ] - tags: [ 'v*' ] - pull_request: - branches: [ main ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - name: Build and Test - - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-unknown-linux-gnu - os: ubuntu-latest - output: cargo-binstall - use-cross: false - test: true - debug_build_args: --no-default-features --features rustls,pkg-config - - target: x86_64-apple-darwin - os: macos-latest - output: cargo-binstall - use-cross: false - test: true - debug_build_args: --no-default-features --features rustls - - target: aarch64-apple-darwin - os: macos-latest - output: cargo-binstall - use-cross: false - test: false - debug_build_args: --no-default-features --features rustls - - target: x86_64-pc-windows-msvc - os: windows-latest - output: cargo-binstall.exe - use-cross: false - test: false - debug_build_args: --no-default-features --features native-tls - release_build_args: --no-default-features --features static,zlib-ng,native-tls - - target: x86_64-unknown-linux-musl - os: ubuntu-latest - output: cargo-binstall - use-cross: false - test: true - debug_build_args: --no-default-features --features rustls - - target: armv7-unknown-linux-musleabihf - os: ubuntu-20.04 - output: cargo-binstall - use-cross: true - test: false - debug_build_args: --no-default-features --features rustls - - target: armv7-unknown-linux-gnueabihf - os: ubuntu-20.04 - output: cargo-binstall - use-cross: true - test: false - debug_build_args: --no-default-features --features rustls - - target: aarch64-unknown-linux-musl - os: ubuntu-latest - output: cargo-binstall - use-cross: true - test: false - debug_build_args: --no-default-features --features rustls - - target: aarch64-unknown-linux-gnu - os: ubuntu-latest - output: cargo-binstall - use-cross: true - test: false - debug_build_args: --no-default-features --features rustls - - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - - - name: Configure toolchain - run: | - rustup toolchain install --profile minimal --no-self-update nightly - rustup default nightly - - - name: Install cross - if: matrix.use-cross - uses: taiki-e/install-action@v1 - with: - tool: cross - - - name: Install host target - if: "!matrix.use-cross" - run: rustup target add ${{ matrix.target }} - - - name: Select compile settings - shell: bash - run: | - jq \ - --arg ref '${{ github.ref }}' \ - --argjson matrix '${{ toJSON(matrix) }}' \ - -nrf ci-scripts/compile-settings.jq \ - | tee -a $GITHUB_ENV - - - name: Configure caching - uses: actions/cache@v3 - with: - path: | - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}-${{ env.COUTPUT }} - restore-keys: | - ${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} - ${{ runner.os }}-cargo-${{ matrix.target }}- - ${{ runner.os }}-cargo- - - - name: Install musl-tools - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} - run: sudo apt-get install -y musl-tools - - - name: Install deps - if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' && !startsWith(github.ref, 'refs/tags/v') }} - run: sudo ./ci-scripts/install-deps.sh - - - name: Build - run: ${{ env.CTOOL }} build ${{ env.CARGS }} - - - name: Copy and rename utility - run: cp target/${{ matrix.target }}/${{ env.COUTPUT }}/${{ matrix.output }} ${{ matrix.output }} - - - name: Test (Unix) - if: ${{ matrix.test && matrix.os != 'windows-latest' }} - run: ./ci-scripts/run_tests_unix.sh ${{ matrix.output }} - - - name: Test (Windows) - if: ${{ matrix.os == 'windows-latest' }} - run: | - ./${{ matrix.output }} binstall --no-confirm cargo-binstall - cargo binstall --help - ./${{ matrix.output }} binstall --manifest-path . --no-confirm cargo-binstall - cargo binstall --help - - - name: Upload output - uses: actions/upload-artifact@v3 - with: - retention-days: 1 - name: "${{ matrix.target }}.${{ matrix.output }}" - path: "${{ matrix.output }}" - - release: - name: Package and release - needs: build - if: ${{ startsWith(github.ref, 'refs/tags/v') }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Get outputs - uses: actions/download-artifact@v3 - with: - path: outputs/ - - - name: Create archives - shell: bash - run: | - set -euxo pipefail - for o in outputs/*; do - pushd "$o" - - cp ../../LICENSE.txt ../../README.md . - - target=$(basename "$o" | cut -d. -f1) - if grep -qE '(apple|windows)' <<< "$target"; then - zip "../cargo-binstall-${target}.zip" * - else - tar cvf "../cargo-binstall-${target}.tgz" * - fi - - popd - done - - - name: Extract release notes - id: notes - shell: bash - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_REPO: ${{ github.repository }} - release_commit: ${{ github.event.head_commit.message }} - run: | - set -euxo pipefail - release_pr=$(head -n1 <<< "${release_commit:-}" | jq -Rr 'split("[()]"; "")[1] // ""') - if [[ -z "$release_pr" ]]; then - echo "::set-output name=notes_json::null" - exit - fi - - gh \ - pr --repo "$GITHUB_REPO" \ - view "$release_pr" \ - --json body \ - --jq '"::set-output name=notes_json::\((.body | split("### Release notes")[1] // "") | tojson)"' - - - name: Publish release - uses: softprops/action-gh-release@50195ba7f6f93d1ac97ba8332a178e008ad176aa - with: - tag_name: ${{ github.ref }} - name: ${{ github.ref }} - body: ${{ fromJSON(steps.notes.outputs.notes_json) }} - append_body: true - files: | - outputs/cargo-binstall-*.zip - outputs/cargo-binstall-*.tgz - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..1d84bc12 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,123 @@ +name: Build + +on: + workflow_call: + inputs: + for_release: + description: "True if the build is for a release" + required: true + default: false + type: boolean + + workflow_dispatch: + inputs: + for_release: + description: "True if the build is for a release" + required: true + default: false + type: boolean + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-unknown-linux-gnu + os: ubuntu-latest + debug_build_args: --no-default-features --features rustls,pkg-config + - target: x86_64-apple-darwin + os: macos-latest + - target: aarch64-apple-darwin + os: macos-latest + - target: x86_64-pc-windows-msvc + os: windows-latest + debug_build_args: --no-default-features --features native-tls + release_build_args: --no-default-features --features static,zlib-ng,native-tls + - target: x86_64-unknown-linux-musl + os: ubuntu-latest + - target: armv7-unknown-linux-musleabihf + os: ubuntu-20.04 + use-cross: true + - target: armv7-unknown-linux-gnueabihf + os: ubuntu-20.04 + use-cross: true + - target: aarch64-unknown-linux-musl + os: ubuntu-latest + use-cross: true + - target: aarch64-unknown-linux-gnu + os: ubuntu-latest + use-cross: true + + runs-on: ${{ matrix.os }} + name: ${{ matrix.target }} + + steps: + - uses: actions/checkout@v2 + + - name: Configure toolchain + run: | + rustup toolchain install --profile minimal --no-self-update nightly + rustup default nightly + + - name: Install cross + if: matrix.use-cross + uses: taiki-e/install-action@v1 + with: + tool: cross + + - name: Install host target + if: "!matrix.use-cross" + run: rustup target add ${{ matrix.target }} + + - name: Select compile settings + shell: bash + run: | + jq \ + --argjson for_release '${{ toJSON(inputs.for_release) }}' \ + --argjson matrix '${{ toJSON(matrix) }}' \ + -nrf ci-scripts/compile-settings.jq \ + | tee -a $GITHUB_ENV + + - name: Configure caching + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}-${{ env.COUTPUT }} + restore-keys: | + ${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} + ${{ runner.os }}-cargo-${{ matrix.target }}- + ${{ runner.os }}-cargo- + + - name: Install musl-tools + if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} + run: sudo apt-get install -y musl-tools + + - name: Install deps + if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' && !startsWith(github.ref, 'refs/tags/v') }} + run: sudo ./ci-scripts/install-deps.sh + + - name: Build + run: ${{ env.CTOOL }} build ${{ env.CARGS }} + + - name: Get output + shell: bash + run: | + cp target/${{ matrix.target }}/${{ env.COUTPUT }}/${{ env.CBIN }} ${{ env.CBIN }} + chmod +x ${{ env.CBIN }} || true + ls -l ${{ env.CBIN }} + + - name: Upload output + uses: actions/upload-artifact@v3 + with: + retention-days: 1 + name: "${{ matrix.target }}.${{ env.CBIN }}" + path: "${{ env.CBIN }}" + diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml new file mode 100644 index 00000000..2e0caf2b --- /dev/null +++ b/.github/workflows/integration.yml @@ -0,0 +1,54 @@ +name: Integration + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + uses: ./.github/workflows/build.yml + with: + for_release: false + + test: + needs: build + + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-apple-darwin + os: macos-latest + bin: cargo-binstall + - target: x86_64-unknown-linux-gnu + os: ubuntu-latest + bin: cargo-binstall + - target: x86_64-unknown-linux-musl + os: ubuntu-latest + bin: cargo-binstall + - target: x86_64-pc-windows-msvc + os: windows-latest + bin: cargo-binstall.exe + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + + - name: Download build + uses: actions/download-artifact@v3 + with: + name: "${{ matrix.target }}.${{ matrix.bin }}" + + - run: chmod +x ${{ matrix.bin }} + if: matrix.os != 'windows-latest' + + - name: Test + shell: bash + run: ./ci-scripts/tests.sh ${{ matrix.bin }} ${{ runner.os }} + diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index 1b245801..fb6cc115 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -61,13 +61,8 @@ jobs: fence=$'```\n' ecnef=$'\n```' - title="release: v${{ inputs.version }}" - body_intro="This is a release PR for version **${{ inputs.version }}**." - body_merge="**Use squash merge.**${nl}Upon merging, this will automatically build the CLI and create a GitHub release. You still need to manually publish the cargo crate." - body_pub="${fence}$ git switch main${nl}$ git pull${nl}$ git checkout v${{ inputs.version }}${nl}$ cargo publish${ecnef}" - body_notes="---${br}_Edit release notes into the section below:_${br}${nl}### Release notes" - - body="${body_intro}${br}${body_merge}${br}${body_pub}${br}${body_notes}${br}" + title='release: v${{ inputs.version }}' + body=$(sed 's/%version%/${{ inputs.version }}/g' ci-scripts/release-pr.txt) gh pr create --title "$title" --body "$body" --base main --head "${{ env.branch_name }}" --label "release" env: diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml deleted file mode 100644 index 14aa604a..00000000 --- a/.github/workflows/release-tag.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Tag a release -on: - push: - branches: - - main - tags-ignore: - - "*" - -jobs: - make-tag: - runs-on: ubuntu-latest - # the commit message will look like: `release: v{version} (#{pr-number})` - if: "startsWith(github.event.head_commit.message, 'release: v')" - steps: - - name: Extract tag from commit message - env: - COMMIT_MESSAGE: ${{ github.event.head_commit.message }} - run: | - set -euxo pipefail - - message="$(head -n1 <<< "$COMMIT_MESSAGE")" - version="$(cut -d ' ' -f 2 <<< "${message}")" - echo "CUSTOM_TAG=${version}" >> $GITHUB_ENV - - - uses: actions/checkout@v2 - - name: Push release tag - id: tag_version - uses: mathieudutour/github-tag-action@v6.0 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - custom_tag: ${{ env.CUSTOM_TAG }} - tag_prefix: '' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..fb7c3417 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,77 @@ +name: Release +on: + push: + branches: + - main + tags-ignore: + - "*" + +jobs: + info: + runs-on: ubuntu-latest + # the commit message will look like: `release: v{version} (#{pr-number})` + if: "startsWith(github.event.head_commit.message, 'release: v')" + outputs: + version: ${{ steps.version.outputs.version }} + notes: ${{ fromJSON(steps.notes.outputs.notes_json) }} + env: + COMMIT_MESSAGE: ${{ github.event.head_commit.message }} + steps: + - uses: actions/checkout@v2 + - name: Extract tag from commit message + id: version + run: ./ci-scripts/extract-tag-from-release-commit.sh + - name: Extract release notes + id: notes + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPO: ${{ github.repository }} + run: ./ci-scripts/extract-release-notes.sh + + tag: + needs: info + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Push release tag + uses: mathieudutour/github-tag-action@v6.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + custom_tag: ${{ needs.info.outputs.version }} + tag_prefix: '' + + build: + needs: info # not really, but just so it fails fast + uses: ./.github/workflows/build.yml + with: + for_release: true + + release: + needs: + - info + - tag + - build + name: Package and release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Get outputs + uses: actions/download-artifact@v3 + with: + path: outputs/ + + - name: Pack archives + run: ./ci-scripts/pack-release-archives.sh + + - name: Publish release + uses: softprops/action-gh-release@50195ba7f6f93d1ac97ba8332a178e008ad176aa + with: + tag_name: ${{ needs.info.outputs.version }} + name: ${{ needs.info.outputs.version }} + body: ${{ needs.info.outputs.notes }} + append_body: true + files: | + outputs/cargo-binstall-*.zip + outputs/cargo-binstall-*.tgz + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 7300234e..1b86a22a 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -1,29 +1,54 @@ name: Unit tests on: - push: - branches: [ main ] pull_request: + push: + branches: + - main env: CARGO_TERM_COLOR: always jobs: test: - name: test - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + os: + - macos + - ubuntu + - windows + + runs-on: ${{ matrix.os }}-latest + name: on ${{ matrix.os }} + steps: - - uses: actions/checkout@v2 - - name: Configure toolchain - run: rustup default stable - - name: Configure caching - uses: actions/cache@v2 - with: - key: ubuntu-latest-stable-testing - path: | - ${{ env.HOME }}/.cargo - target - - name: Install deps - run: sudo ./ci-scripts/install-deps.sh - - name: test - run: cargo test --no-default-features --features pkg-config,native-tls + - uses: actions/checkout@v2 + - name: Configure toolchain + run: | + rustup toolchain install --profile minimal --no-self-update nightly + rustup default nightly + + - name: Configure caching + uses: actions/cache@v3 + with: + path: | + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-unit-tests-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + ${{ runner.os }}-unit-tests + + - name: Install deps + if: matrix.os == 'ubuntu' + run: sudo ./ci-scripts/install-deps.sh + + - name: Test (Unix) + if: matrix.os != 'windows' + run: cargo test --no-default-features --features pkg-config,native-tls + + - name: Test (Windows) + if: matrix.os == 'windows' + run: cargo test --no-default-features --features native-tls diff --git a/ci-scripts/compile-settings.jq b/ci-scripts/compile-settings.jq index 933d1d6e..7c739643 100644 --- a/ci-scripts/compile-settings.jq +++ b/ci-scripts/compile-settings.jq @@ -1,15 +1,16 @@ -if ($ref | startswith("refs/tags/v")) then { +if $for_release then { output: "release", profile: "release", args: ($matrix.release_build_args // ""), } else { output: "debug", profile: "dev", - args: ($matrix.debug_build_args // ""), + args: ($matrix.debug_build_args // "--no-default-features --features rustls"), } end | { - CTOOL: (if $matrix."use-cross" then "cross" else "cargo" end), + CBIN: (if ($matrix.target | test("windows")) then "cargo-binstall.exe" else "cargo-binstall" end), + CTOOL: (if ($matrix."use-cross" // false) then "cross" else "cargo" end), COUTPUT: .output, CARGS: "--target \($matrix.target) --profile \(.profile) \(.args)", } diff --git a/ci-scripts/extract-release-notes.sh b/ci-scripts/extract-release-notes.sh new file mode 100755 index 00000000..3bf70165 --- /dev/null +++ b/ci-scripts/extract-release-notes.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -euxo pipefail + +release_pr=$(head -n1 <<< "${COMMIT_MESSAGE:-}" | jq -Rr 'split("[()]"; "")[1] // ""') +if [[ -z "$release_pr" ]]; then + echo "::set-output name=notes_json::null" + exit +fi + +gh \ + pr --repo "$GITHUB_REPO" \ + view "$release_pr" \ + --json body \ + --jq '"::set-output name=notes_json::\((.body | split("### Release notes")[1] // "") | tojson)"' + + diff --git a/ci-scripts/extract-tag-from-release-commit.sh b/ci-scripts/extract-tag-from-release-commit.sh new file mode 100755 index 00000000..a9b11818 --- /dev/null +++ b/ci-scripts/extract-tag-from-release-commit.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -euxo pipefail + +message="$(head -n1 <<< "$COMMIT_MESSAGE")" +version="$(cut -d ' ' -f 2 <<< "${message}")" +echo "::set-output name=version::${version}" diff --git a/ci-scripts/pack-release-archives.sh b/ci-scripts/pack-release-archives.sh new file mode 100755 index 00000000..d7d322bf --- /dev/null +++ b/ci-scripts/pack-release-archives.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -euxo pipefail + +for o in outputs/*; do + pushd "$o" + + chmod +x cargo-binstall* + cp ../../LICENSE.txt ../../README.md . + + target=$(basename "$o" | cut -d. -f1) + if grep -qE '(apple|windows)' <<< "$target"; then + zip "../cargo-binstall-${target}.zip" * + else + tar cv * | gzip -9 > "../cargo-binstall-${target}.tgz" + fi + + popd +done diff --git a/ci-scripts/release-pr.txt b/ci-scripts/release-pr.txt new file mode 100644 index 00000000..e8fe3f7d --- /dev/null +++ b/ci-scripts/release-pr.txt @@ -0,0 +1,28 @@ +This is a release PR for version **%version%**. + +**Use squash merge.** +Upon merging, this will automatically build the CLI and create a GitHub release. +You still need to manually publish the cargo crate. + +``` +$ git pull +$ git checkout v%version% +$ cargo publish +``` + +--- + +_Edit release notes into the section below:_ + + +### Release notes + +_Binstall is a tool to fetch and install Rust-based executables as binaries. It aims to be a drop-in replacement for `cargo install` in most cases. Install it today with `cargo install cargo-binstall`, from the binaries below, or if you already have it, upgrade with `cargo binstall cargo-binstall`._ + +#### In this release: + +- + +#### Other changes: + +- diff --git a/ci-scripts/run_tests_unix.sh b/ci-scripts/tests.sh similarity index 86% rename from ci-scripts/run_tests_unix.sh rename to ci-scripts/tests.sh index e49b81a0..8bb7bd3c 100755 --- a/ci-scripts/run_tests_unix.sh +++ b/ci-scripts/tests.sh @@ -24,10 +24,13 @@ cargo binstall --help >/dev/null cargo binstall --help >/dev/null # Install binaries using secure mode +min_tls=1.3 +[[ "${2:-}" == "Windows" ]] && min_tls=1.2 # WinTLS on GHA doesn't support 1.3 yet + "./$1" binstall \ --log-level debug \ --secure \ - --min-tls-version 1.3 \ + --min-tls-version $min_tls \ --no-confirm \ cargo-binstall # Test that the installed binaries can be run