From 57417b98cb3691703edeed6cdf5e6f5e96fd1d91 Mon Sep 17 00:00:00 2001 From: matej-almasi <120648152+matej-almasi@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:53:22 +0100 Subject: [PATCH] Add post-release workflow (#6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Matej Almasi <¨almasi.mato@gmail.com¨> --- .github/workflows/post-release.yml | 156 +++++++++++++++++++++++++++++ .github/workflows/release-notes.py | 42 ++++++++ .vscode/settings.json | 2 + 3 files changed, 200 insertions(+) create mode 100644 .github/workflows/post-release.yml create mode 100644 .github/workflows/release-notes.py diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml new file mode 100644 index 0000000..bbd264c --- /dev/null +++ b/.github/workflows/post-release.yml @@ -0,0 +1,156 @@ +# Adapted from crate "typos" (see reference) +# 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/ +# https://github.com/crate-ci/typos + +name: post-release +on: + push: + branches: + - main + tags: + - "v*" + +env: + BIN_NAME: doru + +jobs: + publish-to-crates: + name: Publish to crates.io + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Publish + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} + run: cargo publish + + 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 + shell: bash + if: env.RELEASE_VERSION == '' + run: | + # 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 }}" + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Generate Release Notes + run: | + ./.github/workflows/release-notes.py --tag ${{ env.RELEASE_VERSION }} --output notes-${{ env.RELEASE_VERSION }}.md + cat notes-${{ env.RELEASE_VERSION }}.md + + - name: Create GitHub release + id: release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ env.RELEASE_VERSION }} + release_name: ${{ env.RELEASE_VERSION }} + body_path: notes-${{ env.RELEASE_VERSION }}.md + + build-release: + name: Build release + + needs: create-release + + strategy: + matrix: + build: [linux, linux-arm, win-msvc] + + include: + - build: linux + os: ubuntu-latest + rust: stable + target: x86_64-unknown-linux-gnu + + - build: linux-arm + os: ubuntu-latest + rust: stable + target: aarch64-unknown-linux-gnu + + - build: win-msvc + os: windows-latest + rust: stable + target: x86_64-pc-windows-msvc + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install linker for ARM + if: matrix.target == 'aarch64-unknown-linux-gnu' + run: | + sudo apt update + sudo apt install -y --no-install-recommends aarch64-linux-gnu-gcc + + - name: Install Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + + - name: Build release binary + run: cargo build --target ${{ matrix.target }} --release + + - name: Build archive + shell: bash + run: | + outdir="./target/${{ env.TARGET_DIR }}/release" + staging="${{ env.BIN_NAME }}-${{ needs.create-release.outputs.release_version }}-${{ matrix.target }}" + mkdir -p "$staging"/{complete,doc} + cp {README.md,LICENSE-*} "$staging/" + cp {CHANGELOG.md,docs/*} "$staging/doc/" + if [ "${{ matrix.os }}" = "windows-latest" ]; then + cp "target/${{ matrix.target }}/release/${{ env.BIN_NAME }}.exe" "$staging/" + cd "$staging" + 7z a "../$staging.zip" . + echo "ASSET=$staging.zip" >> $GITHUB_ENV + else + cp "target/${{ matrix.target }}/release/${{ env.BIN_NAME }}" "$staging/" + tar czf "$staging.tar.gz" -C "$staging" . + echo "ASSET=$staging.tar.gz" >> $GITHUB_ENV + fi + + - name: Upload release archive + 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 diff --git a/.github/workflows/release-notes.py b/.github/workflows/release-notes.py new file mode 100644 index 0000000..f36d020 --- /dev/null +++ b/.github/workflows/release-notes.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 + +import argparse +import pathlib +import sys + + +_STDIO = pathlib.Path("-") + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("-i", "--input", type=pathlib.Path, default="CHANGELOG.md") + parser.add_argument("--tag", required=True) + parser.add_argument("-o", "--output", type=pathlib.Path, required=True) + args = parser.parse_args() + + if args.input == _STDIO: + lines = sys.stdin.readlines() + else: + with args.input.open() as fh: + lines = fh.readlines() + version = args.tag.lstrip("v") + + note_lines = [] + for line in lines: + if line.startswith("## ") and version in line: + note_lines.append(line) + elif note_lines and line.startswith("## "): + break + elif note_lines: + note_lines.append(line) + + notes = "".join(note_lines).strip() + if args.output == _STDIO: + print(notes) + else: + args.output.write_text(notes) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 68cdc43..5320370 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,8 @@ "cSpell.words": [ "binop", "doru", + "liblz4", + "pkgid", "serde", "thiserror" ]