From c155b6f98d0972d4495dc1495591819cda6d550d Mon Sep 17 00:00:00 2001 From: Danilo Bargen Date: Thu, 30 Dec 2021 22:37:39 +0100 Subject: [PATCH] CI: Clean up release workflow and upload script - Clean up scripts - Create draft release before uploading assets - Find release for current tag, don't simply pick the latest - Add Windows builds - Add checksums for binaries --- .github/workflows/release.yml | 112 ++++++++++++++++++++++++---------- scripts/upload-asset.sh | 88 ++++++++++++++++++++++++++ upload-asset.sh | 37 ----------- 3 files changed, 169 insertions(+), 68 deletions(-) create mode 100644 scripts/upload-asset.sh delete mode 100644 upload-asset.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 974d873..c0a7f1c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,38 +4,51 @@ on: - "v*" # push events to matching v*, i.e. v1.0, v20.15.10 jobs: - completions-upload: - runs-on: ubuntu-latest + create-release: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Create release for tag + if: startsWith(github.ref, 'refs/tags/') + run: | + source ./scripts/upload-asset.sh + # Create: + create_release ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} "Tealdeer version ${GITHUB_REF#refs/*/v}.\n\nFor the full changelog, see https://github.com/dbrgn/tealdeer/blob/main/CHANGELOG.md.\n\nBinaries were generated automatically in CI, and are therefore unsigned. For a fully trusted release, please build from source." + + upload-completions: + needs: + - create-release + runs-on: ubuntu-20.04 strategy: matrix: target: ["bash", "fish", "zsh"] steps: - uses: actions/checkout@v2 - - name: Upload + - name: Upload completion if: startsWith(github.ref, 'refs/tags/') run: | - sudo apt update && sudo apt install -y jq - source ./upload-asset.sh + source ./scripts/upload-asset.sh + # Upload: + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} ${{ matrix.target }}_tealdeer completions_${{ matrix.target }} - upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${{ matrix.target }}_tealdeer completions_${{ matrix.target }} - - license-upload: - runs-on: ubuntu-latest + upload-license: + needs: + - create-release + runs-on: ubuntu-20.04 strategy: matrix: target: ["MIT", "APACHE"] steps: - uses: actions/checkout@v2 - - name: Upload + - name: Upload license if: startsWith(github.ref, 'refs/tags/') run: | - sudo apt update && sudo apt install -y jq - source ./upload-asset.sh - - upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} LICENSE-${{ matrix.target }} LICENSE-${{ matrix.target }} + source ./scripts/upload-asset.sh + # Upload: + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} LICENSE-${{ matrix.target }} LICENSE-${{ matrix.target }}.txt build-linux: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 strategy: matrix: include: @@ -49,22 +62,21 @@ jobs: libc: "musleabi" - arch: "arm" libc: "musleabihf" - steps: - uses: actions/checkout@v2 - - name: Docker Pull + - name: Pull Docker image run: docker pull messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} - - name: Build with Docker + - name: Build in Docker run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} cargo build --release - - name: Stripping + - name: Strip binary run: docker run --rm -i -v "$(pwd)":/home/rust/src messense/rust-musl-cross:${{ matrix.arch }}-${{ matrix.libc }} musl-strip -s /home/rust/src/target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr - uses: actions/upload-artifact@v2 with: - name: "tldr-linux-${{ matrix.arch }}-${{ matrix.libc }}" + name: "tealdeer-linux-${{ matrix.arch }}-${{ matrix.libc }}" path: "target/${{ matrix.arch }}-unknown-linux-${{ matrix.libc }}/release/tldr" - build-darwin: - runs-on: macos-latest + build-macos: + runs-on: macos-11 steps: - uses: actions/checkout@v2 - name: Build @@ -74,24 +86,62 @@ jobs: args: --release --target x86_64-apple-darwin - uses: actions/upload-artifact@v2 with: - name: "tldr-apple-darwin-x86_64" + name: "tealdeer-macos-x86_64" path: "target/x86_64-apple-darwin/release/tldr" - release-upload: + build-windows: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v2 + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + args: --release --target x86_64-pc-windows-msvc + - uses: actions/upload-artifact@v2 + with: + name: "tealdeer-windows-x86_64-msvc" + path: "target/x86_64-pc-windows-msvc/release/tldr.exe" + + upload-release: needs: + - create-release - build-linux - - build-darwin - runs-on: ubuntu-latest + - build-macos + - build-windows + runs-on: ubuntu-20.04 strategy: matrix: - target: ["linux-x86_64-musl", "linux-i686-musl", "linux-armv7-musleabihf", "linux-arm-musleabi", "linux-arm-musleabihf", "apple-darwin-x86_64"] + target: + - linux-x86_64-musl + - linux-i686-musl + - linux-armv7-musleabihf + - linux-arm-musleabi + - linux-arm-musleabihf + - macos-x86_64 + - windows-x86_64-msvc steps: - uses: actions/checkout@v2 - uses: actions/download-artifact@v2 - - name: Upload + - name: Upload binary if: startsWith(github.ref, 'refs/tags/') run: | - sudo apt update && sudo apt install -y jq - source ./upload-asset.sh + source ./scripts/upload-asset.sh - upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} tldr-${{ matrix.target }}/tldr tldr-${{ matrix.target }} + # Move/rename file + mkdir out && cd out + if [[ "${{ matrix.target }}" == *windows* ]]; then + src="../tealdeer-${{ matrix.target }}/tldr.exe" + filename="tealdeer-${{ matrix.target }}.exe" + else + src="../tealdeer-${{ matrix.target }}/tldr" + filename="tealdeer-${{ matrix.target }}" + fi + cp $src $filename + + # Create checksum + sha256sum "$filename" > "$filename.sha256" + + # Upload: + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} $filename $filename + upload_release_file ${{ secrets.GITHUB_TOKEN }} ${{ github.repository }} ${GITHUB_REF#refs/*/} $filename.sha256 $filename.sha256 diff --git a/scripts/upload-asset.sh b/scripts/upload-asset.sh new file mode 100644 index 0000000..7f0a9c3 --- /dev/null +++ b/scripts/upload-asset.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# +# Upload artifacts to GitHub Actions. +# +# Based on: https://gist.github.com/schell/2fe896953b6728cc3c5d8d5f9f3a17a3 +# +# Requires curl and jq on PATH + +# Args: +# token: GitHub API user token +# repo: GitHub username/reponame +# tag: Name of the tag for which to create a release +# description: Release description +create_release() { + # Args + token=$1 + repo=$2 + tag=$3 + description=$4 + echo "Creating release:" + echo " repo=$repo" + echo " tag=$tag" + echo "" + + # Create release + http_code=$( + curl -s -o create.json -w '%{http_code}' \ + --header "Accept: application/vnd.github.v3+json" \ + --header "Authorization: Bearer $token" \ + --header "Content-Type:application/json" \ + "https://api.github.com/repos/$repo/releases" \ + -d '{"tag_name":"'"$tag"'","name":"'"${tag/v/Release }"'","draft":true,"body":"'"${description/\"/\\\"}"'"}' + ) + if [ "$http_code" == "201" ]; then + echo "Release for tag $tag created." + else + echo "Asset upload failed with code '$http_code'." + return 1 + fi +} + +# Args: +# token: GitHub API user token +# repo: GitHub username/reponame +# tag: Name of the tag for which to upload the assets +# file: Path to the asset file to upload +# name: Name to use for the uploaded asset +upload_release_file() { + # Args + token=$1 + repo=$2 + tag=$3 + file=$4 + name=$5 + echo "Uploading:" + echo " repo=$repo" + echo " tag=$tag" + echo " file=$file" + echo " name=$name" + echo "" + + # Determine upload URL of latest draft release for the specified tag + upload_url=$( + curl -s \ + --header "Accept: application/vnd.github.v3+json" \ + --header "Authorization: Bearer $token" \ + "https://api.github.com/repos/$repo/releases" \ + | jq -r '[.[] | select(.tag_name == "'"$tag"'" and .draft)][0].upload_url' \ + | cut -d"{" -f'1' + ) + echo "Determined upload URL: $upload_url" + http_code=$( + curl -s -o upload.json -w '%{http_code}' \ + --request POST \ + --header "Accept: application/vnd.github.v3+json" \ + --header "Authorization: Bearer $token" \ + --header "Content-Type: application/octet-stream" \ + --data-binary "@$file" "$upload_url?name=$name" + ) + if [ "$http_code" == "201" ]; then + echo "Asset $name uploaded:" + jq -r .browser_download_url upload.json + else + echo "Asset upload failed with code '$http_code':" + cat upload.json + return 1 + fi +} diff --git a/upload-asset.sh b/upload-asset.sh deleted file mode 100644 index af85fbf..0000000 --- a/upload-asset.sh +++ /dev/null @@ -1,37 +0,0 @@ -#! /bin/bash -# https://gist.github.com/schell/2fe896953b6728cc3c5d8d5f9f3a17a3 -# requires curl and jq on PATH: https://stedolan.github.io/jq/ - -# upload a release file. -# this must be called only after a successful create_release, as create_release saves -# the json response in release.json. -# token: github api user token -# repo: github username/reponame -# file: path to the asset file to upload -# name: name to use for the uploaded asset -upload_release_file() { - token=$1 - repo=$2 - file=$3 - name=$4 - - url=`curl --silent "https://api.github.com/repos/${repo}/releases/latest" | jq -r .upload_url | cut -d{ -f'1'` - command="\ - curl -s -o upload.json -w '%{http_code}' \ - --request POST \ - --header 'authorization: Bearer ${token}' \ - --header 'Content-Type: application/octet-stream' \ - --data-binary @\"${file}\" - ${url}?name=${name}" - http_code=`eval $command` - if [ $http_code == "201" ]; then - echo "asset $name uploaded:" - jq -r .browser_download_url upload.json - else - echo "upload failed with code '$http_code':" - cat upload.json - echo "command:" - echo $command - return 1 - fi -}