From b6e0de0610b8d9549b9627f6791009cd9f6690f1 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Fri, 28 Apr 2023 23:48:44 +0100 Subject: [PATCH 1/3] ci: Add release workflow for draft release with all sources as asset Create a GitHub workflow that runs when new tags are created, in order to create a draft release containing a new asset: an archive with all sources required to build veristat, in other words, the sources of veristat and of its libbpf submodule. The draft release is at https://github.com/libbpf/veristat/releases, and needs to be published manually. Note that the release author will be "github-actions" instead of the person who manually publishes from the draft. The motivation for adding an archive with the sources of both veristat and libbpf is to help with packaging: there is only one archive to handle to get all the sources, without having to care about git submodules. Signed-off-by: Quentin Monnet --- .github/workflows/release.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ae0ebff --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,34 @@ +name: release + +on: + push: + tags: + - '**' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.after }} + cancel-in-progress: true + +jobs: + draft-release: + name: Create a draft release + runs-on: ubuntu-22.04 + permissions: + contents: write + steps: + - name: Checkout veristat and libbpf code + uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 + with: + submodules: recursive + path: 'veristat' + + - name: Package source code including submodules + run: | + tar -I 'gzip -9' --exclude-vcs \ + -cvf "veristat-all-sources-${{ github.ref_name }}.tar.gz" veristat + + - name: Create draft release and add artifacts + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 + with: + draft: true + files: veristat* From 4b53a495119ff14c8d5e59f3c9d0dcde47296ab0 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Fri, 28 Apr 2023 23:54:54 +0100 Subject: [PATCH 2/3] ci: Extend release workflow to add static amd64/arm64 builds Now that we have a release workflow, we can also use it to ship (statically-built) binaries. This commit builds veristat both for amd64 (the arch of the GitHub runner) and arm64 (using QEMU to cross-compile). Signed-off-by: Quentin Monnet --- .github/workflows/release.yml | 84 +++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ae0ebff..d2fa00f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,12 +10,96 @@ concurrency: cancel-in-progress: true jobs: + build: + name: Build static veristat binary + runs-on: ubuntu-22.04 + env: + TARGETARCH: ${{ matrix.arch }} + FILE_STRING_ARCH_amd64: x86-64 + FILE_STRING_ARCH_arm64: aarch64 + strategy: + matrix: + arch: [arm64, amd64] + + steps: + # amd64 needs the dependencies to build veristat + - name: Install dependencies (amd64) + if: matrix.arch == 'amd64' + run: | + sudo apt-get update + sudo apt-get install -y libelf-dev + + - name: Checkout veristat code + uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 + with: + submodules: recursive + path: 'veristat' + + - name: Build static veristat natively for amd64 + if: matrix.arch == 'amd64' + working-directory: 'veristat' + run: | + EXTRA_CFLAGS=--static \ + make -j -C src V=1 + strip src/veristat + + - name: Set up QEMU + uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2.1.0 + if: matrix.arch == 'arm64' + with: + platforms: arm64 + + # The emulated build leverages Docker and Ubuntu 22.04 container image + # distribution to have all the needed arm64 packages. + - name: Build static veristat for arm64 with emulation + if: matrix.arch == 'arm64' + run: | + docker run --platform linux/arm64 --rm -v $(pwd):/build ubuntu:22.04 \ + bash -c "apt-get update && \ + apt-get install -y make pkg-config gcc libelf-dev && \ + cd /build/veristat && \ + EXTRA_CFLAGS=--static \ + make -j -C src V=1 && \ + strip src/veristat" + + - name: Test veristat binary + working-directory: 'veristat/src' + env: + ARCH: ${{ env[format('FILE_STRING_ARCH_{0}', matrix.arch)] }} + run: | + file ./veristat | \ + tee /dev/stderr | \ + grep -q "${{ env.ARCH }}" + ./veristat --usage | grep -q Usage + ldd ./veristat 2>&1 | \ + tee /dev/stderr | \ + grep -q 'not a dynamic executable' + + - name: Upload Artifact + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + with: + name: ${{ format('veristat_{0}', matrix.arch) }} + path: veristat/src/veristat + draft-release: name: Create a draft release runs-on: ubuntu-22.04 + needs: build permissions: contents: write steps: + - name: Download artifacts from build + uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + + - name: Rename binaries and compress + run: | + archive_amd64="veristat-${{ github.ref_name }}-amd64.tar.gz" + archive_arm64="veristat-${{ github.ref_name }}-arm64.tar.gz" + tar -C veristat_amd64 -I 'gzip -9' -cvf "${archive_amd64}" veristat + tar -C veristat_arm64 -I 'gzip -9' -cvf "${archive_arm64}" veristat + sha256sum "${archive_amd64}" > "${archive_amd64}.sha256sum" + sha256sum "${archive_arm64}" > "${archive_arm64}.sha256sum" + - name: Checkout veristat and libbpf code uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3.5.0 with: From 5ca2a80060acf78f561085a1063c9bb8aa319a40 Mon Sep 17 00:00:00 2001 From: Quentin Monnet Date: Fri, 28 Apr 2023 23:34:22 +0100 Subject: [PATCH 3/3] scripts: Add script to rename (add label to) release assets The only way I've found to add a label to existing release assets on GitHub is via the GitHub API. Add a script to "rename" (add a label) to existing assets. In particular, we rename the archive containing the sources for veristat and its libbpf submodule. Example invocation (with REPO modified to point to my fork): $ ./scripts/gh-label-release-assets.sh test02 repo: qmonnet/veristat, release tag: test02 found release ID 101340990 found asset ID 105863030 asset 'veristat-all-sources-test02.tar.gz': add label 'Full source code with submodules (tar.gz)' proceed? [y/N]: y [ ... JSON output from server reply to API request ... ] After running the script, instead of being listed as "veristat-all-sources-.tar.gz", the asset appears on GitHub's interface as "Full source code with submodules (tar.gz)". More assets could easily be renamed as well by extending the array in the script. The script is not run from CI, because it requires the release to be published (we only automated the creation of the draft release). The script requires the GitHub command line ("gh") to be set up. If the asset is found but the update fails with a 404 error, this is usually synonymous with insufficient permissions for the GitHub token in use. Signed-off-by: Quentin Monnet --- scripts/gh-label-release-assets.sh | 94 ++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100755 scripts/gh-label-release-assets.sh diff --git a/scripts/gh-label-release-assets.sh b/scripts/gh-label-release-assets.sh new file mode 100755 index 0000000..83221e0 --- /dev/null +++ b/scripts/gh-label-release-assets.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + +set -o errexit +set -o nounset +set -o pipefail + +# Use this script to add labels to GitHub release assets for a given release. +# +# Based on the following console workflow: +# +# gh api \ +# '/repos/libbpf/veristat/releases/tags/' \ +# --jq '.id' +# gh api \ +# '/repos/libbpf/veristat/releases//assets' \ +# --jq '.[] | select(.name == "").id' +# gh api \ +# --method PATCH \ +# -H "Accept: application/vnd.github+json" \ +# -H "X-GitHub-Api-Version: 2022-11-28" \ +# '/repos/libbpf/veristat/releases/assets/' \ +# -f name='' \ +# -f label='' + +REPO="libbpf/veristat" + +usage() { + echo "Update asset labels for veristat releases" + echo "Usage:" + echo " $0 [options] " + echo "" + echo "OPTIONS" + echo " -h display this help" + exit "$1" +} + +OPTIND=1 +while getopts "h" opt; do + case "$opt" in + h) + usage 0 + ;; + *) + usage 1 + ;; + esac +done +shift $((OPTIND-1)) +[[ "${1:-}" = "--" ]] && shift + +# Get release tag from command line +if [[ "$#" -lt 1 ]]; then + echo "error: missing release tag" + usage 1 +fi +release_tag="$1" +echo "repo: ${REPO}, release tag: ${release_tag}" + +# Add labels to set for given asset names here: +declare -A assets_labels=( + ["veristat-all-sources-${release_tag}.tar.gz"]="Full source code with submodules (tar.gz)" +) + +# Get release ID +release_id="$(gh api "/repos/${REPO}/releases/tags/${release_tag}" --jq '.id')" +echo " found release ID ${release_id}" + +# For each label to set, get asset ID, prompt user for confirmation, set label +for asset_name in "${!assets_labels[@]}"; do + asset_id="$(gh api "/repos/${REPO}/releases/${release_id}/assets" \ + --jq ".[] | select(.name == \"${asset_name}\").id")" + echo " found asset ID ${asset_id}" + + echo "asset '${asset_name}': add label '${assets_labels[${asset_name}]}'" + answer="" + read -rp 'proceed? [y/N]: ' answer + + case "${answer}" in + y|yes|Y|Yes|YES) + # Note: A 404 error at this stage may be synonymous with + # insufficient permissions for the token in use for gh. + gh api \ + --method PATCH \ + -H 'Accept: application/vnd.github+json' \ + -H 'X-GitHub-Api-Version: 2022-11-28' \ + "/repos/${REPO}/releases/assets/${asset_id}" \ + -f label="${assets_labels[${asset_name}]}" + ;; + *) + echo "cancelled" + ;; + esac +done