From c43de1bd2ae3bd0caf79e20a0b7dd06f987ae985 Mon Sep 17 00:00:00 2001 From: Alexey <247128645+axkurcom@users.noreply.github.com> Date: Tue, 24 Mar 2026 22:36:25 +0300 Subject: [PATCH] Update release.yml --- .github/workflows/release.yml | 242 ++++++++++++++++++++++++++-------- 1 file changed, 186 insertions(+), 56 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 28ad853..5e21a85 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,26 +5,68 @@ on: tags: - '[0-9]+.[0-9]+.[0-9]+' workflow_dispatch: + inputs: + tag: + description: 'Release tag (example: 3.3.15)' + required: true + type: string concurrency: - group: release-${{ github.ref }} + group: release-${{ github.ref_name }}-${{ github.event.inputs.tag || 'auto' }} cancel-in-progress: true permissions: contents: read - packages: write env: CARGO_TERM_COLOR: always BINARY_NAME: telemt jobs: -# ========================== -# GNU / glibc -# ========================== + prepare: + name: Prepare + runs-on: ubuntu-latest + + outputs: + version: ${{ steps.vars.outputs.version }} + prerelease: ${{ steps.vars.outputs.prerelease }} + + steps: + - name: Resolve version + id: vars + shell: bash + run: | + set -euo pipefail + + if [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then + VERSION="${{ github.event.inputs.tag }}" + else + VERSION="${GITHUB_REF#refs/tags/}" + fi + + VERSION="${VERSION#refs/tags/}" + + if [ -z "${VERSION}" ]; then + echo "Release version is empty" >&2 + exit 1 + fi + + if [[ "${VERSION}" == *-* ]]; then + PRERELEASE=true + else + PRERELEASE=false + fi + + echo "version=${VERSION}" >> "${GITHUB_OUTPUT}" + echo "prerelease=${PRERELEASE}" >> "${GITHUB_OUTPUT}" + + # ========================== + # GNU / glibc + # ========================== build-gnu: name: GNU ${{ matrix.asset }} runs-on: ubuntu-latest + needs: prepare container: image: rust:slim-bookworm @@ -69,13 +111,19 @@ jobs: - uses: actions/cache@v4 with: path: | - ~/.cargo/registry - ~/.cargo/git + /usr/local/cargo/registry + /usr/local/cargo/git target - key: gnu-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} + key: gnu-${{ matrix.asset }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + gnu-${{ matrix.asset }}- + gnu- - name: Build + shell: bash run: | + set -euo pipefail + if [ "${{ matrix.target }}" = "aarch64-unknown-linux-gnu" ]; then export CC=aarch64-linux-gnu-gcc export CXX=aarch64-linux-gnu-g++ @@ -90,34 +138,38 @@ jobs: CPU_FLAGS="-C target-cpu=x86-64" fi - export RUSTFLAGS="-C linker=clang -C link-arg=-fuse-ld=lld -C lto=fat -C panic=abort $CPU_FLAGS" + export RUSTFLAGS="-C linker=clang -C link-arg=-fuse-ld=lld -C lto=fat -C panic=abort ${CPU_FLAGS}" fi - cargo build --release --target ${{ matrix.target }} + cargo build --release --target ${{ matrix.target }} -j "$(nproc)" - name: Package + shell: bash run: | + set -euo pipefail + mkdir -p dist - cp target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} dist/telemt + cp "target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}" dist/telemt cd dist - tar -czf ${{ matrix.asset }}.tar.gz \ + tar -czf "${{ matrix.asset }}.tar.gz" \ --owner=0 --group=0 --numeric-owner \ telemt - sha256sum ${{ matrix.asset }}.tar.gz > ${{ matrix.asset }}.sha256 + sha256sum "${{ matrix.asset }}.tar.gz" > "${{ matrix.asset }}.tar.gz.sha256" - uses: actions/upload-artifact@v4 with: name: ${{ matrix.asset }} path: dist/* -# ========================== -# MUSL -# ========================== + # ========================== + # MUSL + # ========================== build-musl: name: MUSL ${{ matrix.asset }} runs-on: ubuntu-latest + needs: prepare container: image: rust:slim-bookworm @@ -149,6 +201,38 @@ jobs: pkg-config \ curl + - uses: actions/cache@v4 + if: matrix.target == 'aarch64-unknown-linux-musl' + with: + path: ~/.musl-aarch64 + key: musl-toolchain-aarch64-v1 + + - name: Install aarch64 musl toolchain + if: matrix.target == 'aarch64-unknown-linux-musl' + shell: bash + run: | + set -euo pipefail + + TOOLCHAIN_DIR="$HOME/.musl-aarch64" + ARCHIVE="aarch64-linux-musl-cross.tgz" + URL="https://github.com/telemt/telemt/releases/download/toolchains/${ARCHIVE}" + + if [ -x "${TOOLCHAIN_DIR}/bin/aarch64-linux-musl-gcc" ]; then + echo "MUSL toolchain cached" + else + curl -fL \ + --retry 5 \ + --retry-delay 3 \ + --connect-timeout 10 \ + --max-time 120 \ + -o "${ARCHIVE}" "${URL}" + + mkdir -p "${TOOLCHAIN_DIR}" + tar -xzf "${ARCHIVE}" --strip-components=1 -C "${TOOLCHAIN_DIR}" + fi + + echo "${TOOLCHAIN_DIR}/bin" >> "${GITHUB_PATH}" + - name: Add rust target run: rustup target add ${{ matrix.target }} @@ -158,10 +242,16 @@ jobs: /usr/local/cargo/registry /usr/local/cargo/git target - key: musl-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} + key: musl-${{ matrix.asset }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + musl-${{ matrix.asset }}- + musl- - name: Build + shell: bash run: | + set -euo pipefail + if [ "${{ matrix.target }}" = "aarch64-unknown-linux-musl" ]; then export CC=aarch64-linux-musl-gcc export CC_aarch64_unknown_linux_musl=aarch64-linux-musl-gcc @@ -176,32 +266,38 @@ jobs: CPU_FLAGS="-C target-cpu=x86-64" fi - export RUSTFLAGS="-C target-feature=+crt-static -C lto=fat -C panic=abort $CPU_FLAGS" + export RUSTFLAGS="-C target-feature=+crt-static -C lto=fat -C panic=abort ${CPU_FLAGS}" fi - cargo build --release --target ${{ matrix.target }} + cargo build --release --target ${{ matrix.target }} -j "$(nproc)" - name: Package + shell: bash run: | + set -euo pipefail + mkdir -p dist - cp target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} dist/telemt + cp "target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}" dist/telemt cd dist - tar -czf ${{ matrix.asset }}.tar.gz telemt - sha256sum ${{ matrix.asset }}.tar.gz > ${{ matrix.asset }}.sha256 + tar -czf "${{ matrix.asset }}.tar.gz" \ + --owner=0 --group=0 --numeric-owner \ + telemt + + sha256sum "${{ matrix.asset }}.tar.gz" > "${{ matrix.asset }}.tar.gz.sha256" - uses: actions/upload-artifact@v4 with: name: ${{ matrix.asset }} path: dist/* -# ========================== -# Release -# ========================== + # ========================== + # Release + # ========================== release: name: Release runs-on: ubuntu-latest - needs: [build-gnu, build-musl] + needs: [prepare, build-gnu, build-musl] permissions: contents: write @@ -211,23 +307,30 @@ jobs: with: path: artifacts - - run: | - mkdir dist + - name: Flatten artifacts + shell: bash + run: | + set -euo pipefail + mkdir -p dist find artifacts -type f -exec cp {} dist/ \; - - uses: softprops/action-gh-release@v2 + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 with: + tag_name: ${{ needs.prepare.outputs.version }} + target_commitish: ${{ github.sha }} files: dist/* generate_release_notes: true - prerelease: ${{ contains(github.ref, '-') }} + prerelease: ${{ needs.prepare.outputs.prerelease == 'true' }} + overwrite_files: true -# ========================== -# Docker (FROM RELEASE) -# ========================== + # ========================== + # Docker + # ========================== docker: name: Docker runs-on: ubuntu-latest - needs: release + needs: [prepare, release] permissions: contents: read @@ -236,26 +339,8 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Extract version - id: vars - run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT - - - name: Download binaries from release - run: | - mkdir -p bin - VERSION=${{ steps.vars.outputs.VERSION }} - - base_url="https://github.com/${{ github.repository }}/releases/download/$VERSION" - - curl -fL -o amd64.tar.gz "$base_url/telemt-x86_64-linux-musl.tar.gz" - tar -xzf amd64.tar.gz - mv telemt bin/telemt-amd64 - - curl -fL -o arm64.tar.gz "$base_url/telemt-aarch64-linux-musl.tar.gz" - tar -xzf arm64.tar.gz - mv telemt bin/telemt-arm64 - - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 @@ -264,12 +349,57 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Probe release assets + shell: bash + env: + VERSION: ${{ needs.prepare.outputs.version }} + run: | + set -euo pipefail + + for asset in \ + telemt-x86_64-linux-musl.tar.gz \ + telemt-x86_64-linux-musl.tar.gz.sha256 \ + telemt-aarch64-linux-musl.tar.gz \ + telemt-aarch64-linux-musl.tar.gz.sha256 + do + curl -fsIL \ + --retry 10 \ + --retry-delay 3 \ + "https://github.com/${GITHUB_REPOSITORY}/releases/download/${VERSION}/${asset}" \ + > /dev/null + done + + - name: Compute image tags + id: meta + shell: bash + env: + VERSION: ${{ needs.prepare.outputs.version }} + run: | + set -euo pipefail + + IMAGE="$(echo "ghcr.io/${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')" + TAGS="${IMAGE}:${VERSION}" + + if [[ "${VERSION}" != *-* ]]; then + TAGS="${TAGS}"$'\n'"${IMAGE}:latest" + fi + + { + echo "tags<> "${GITHUB_OUTPUT}" + - name: Build & Push uses: docker/build-push-action@v6 with: context: . push: true + pull: true platforms: linux/amd64,linux/arm64 - tags: | - ghcr.io/${{ github.repository }}:${{ steps.vars.outputs.VERSION }} - ghcr.io/${{ github.repository }}:latest + tags: ${{ steps.meta.outputs.tags }} + build-args: | + TELEMT_REPOSITORY=${{ github.repository }} + TELEMT_VERSION=${{ needs.prepare.outputs.version }} + cache-from: type=gha + cache-to: type=gha,mode=max