name: Release on: push: tags: - 'v*' permissions: contents: write env: CARGO_TERM_COLOR: always RUST_BACKTRACE: short RUSTFLAGS: -D warnings jobs: build: name: build ${{ matrix.target }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: include: - target: x86_64-unknown-linux-gnu apt: "" rustflags: "-D warnings" - target: aarch64-unknown-linux-gnu # gcc-aarch64-linux-gnu ships the cross compiler/binutils # but no target libc; libc6-dev-arm64-cross adds Scrt1.o, # crti.o, and friends needed at link time. apt: "gcc-aarch64-linux-gnu libc6-dev-arm64-cross" rustflags: "-D warnings" - target: x86_64-unknown-linux-musl apt: "musl-tools" rustflags: "-D warnings" - target: aarch64-unknown-linux-musl apt: "" rustflags: "-D warnings -C linker=rust-lld -C link-self-contained=yes" steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@1.83 with: targets: ${{ matrix.target }} - name: Install cross toolchain if: matrix.apt != '' run: | sudo apt-get update -qq sudo apt-get install -y --no-install-recommends ${{ matrix.apt }} - name: Cache cargo state uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-release-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-release-${{ matrix.target }}- - name: Build nuwiki-ls env: # Per-target linker overrides. Cargo ignores the entries that # don't match the current target, so setting all of them here # keeps the matrix declarative. CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc RUSTFLAGS: ${{ matrix.rustflags }} run: cargo build --release --target ${{ matrix.target }} -p nuwiki-ls - name: Package archive id: package run: | set -euo pipefail version="${GITHUB_REF_NAME#v}" archive="nuwiki-ls-${version}-${{ matrix.target }}.tar.gz" tar -czf "$archive" -C "target/${{ matrix.target }}/release" nuwiki-ls # Use a stable name without version so /releases/latest/download/nuwiki-ls-{target}.tar.gz always resolves. stable="nuwiki-ls-${{ matrix.target }}.tar.gz" mv "$archive" "$stable" echo "archive=$stable" >> "$GITHUB_OUTPUT" - name: Upload build artifact uses: actions/upload-artifact@v3 with: name: nuwiki-ls-${{ matrix.target }} path: ${{ steps.package.outputs.archive }} if-no-files-found: error release: name: gitea release needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Download all build artifacts # download-artifact@v3 nests each artifact under its own dir # (artifacts//), so recurse. uses: actions/download-artifact@v3 with: path: ./artifacts - name: Ensure jq + curl run: | if ! command -v jq >/dev/null 2>&1; then apt-get update && apt-get install -y --no-install-recommends jq fi if ! command -v curl >/dev/null 2>&1; then apt-get update && apt-get install -y --no-install-recommends curl fi - name: Generate release notes id: notes run: | set -euo pipefail # Get commits since the previous tag (or the first commit if this is the first release). prev_tag=$(git tag --sort=-version:refname | awk "NR==2" || echo "") if [ -n "$prev_tag" ]; then log=$(git log --oneline "$prev_tag"..HEAD) else log=$(git log --oneline --max-parents=0..HEAD) fi # Write notes to a file for later use. cat > release-notes.txt </dev/null || true) if [ "$existing" = "200" ]; then echo "Release for $TAG already exists — fetching existing id" release_id=$(curl --fail --silent --show-error \ -H "Authorization: token $RELEASE_TOKEN" \ "$GITEA_SERVER/api/v1/repos/$REPO/releases/tags/$TAG" \ | jq -r '.id') else notes=$(cat release-notes.txt 2>/dev/null || echo "") payload=$(jq -n --arg tag "$TAG" --arg name "$TAG" --arg body "$notes" \ '{tag_name: $tag, name: $name, body: $body, draft: false, prerelease: false}') release_id=$(curl --fail --silent --show-error \ -H "Authorization: token $RELEASE_TOKEN" \ -H "Content-Type: application/json" \ -d "$payload" \ "$GITEA_SERVER/api/v1/repos/$REPO/releases" \ | jq -r '.id') if [ -z "$release_id" ] || [ "$release_id" = "null" ]; then echo "::error::failed to create release" exit 1 fi echo "Created release id=$release_id" fi # download-artifact@v3 nests each artifact under its own dir # (artifacts//), so recurse. for archive in $(find artifacts -name '*.tar.gz' -type f); do name="$(basename "$archive")" echo "Uploading $name …" curl --fail --silent --show-error \ -H "Authorization: token $RELEASE_TOKEN" \ -H "Content-Type: application/gzip" \ --data-binary "@$archive" \ "$GITEA_SERVER/api/v1/repos/$REPO/releases/$release_id/assets?name=$name" \ >/dev/null done echo "All assets uploaded."