bd729d513d
CI / cargo fmt --check (push) Successful in 29s
CI / cargo clippy (push) Successful in 35s
CI / cargo test (push) Successful in 52s
Release / build x86_64-unknown-linux-gnu (push) Successful in 50s
Release / build x86_64-unknown-linux-musl (push) Successful in 56s
CI / editor keymaps (push) Successful in 1m55s
Release / build aarch64-unknown-linux-gnu (push) Successful in 3m16s
Release / build aarch64-unknown-linux-musl (push) Successful in 4m23s
Release / gitea release (push) Successful in 1m40s
The release notes were generated but never passed to the Gitea API. Also suppress the expected 404 from the idempotency check.
193 lines
7.0 KiB
YAML
193 lines
7.0 KiB
YAML
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/<artifact-name>/<file>), 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 <<EOF
|
|
**Full Changelog**: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/compare/${prev_tag:-$(git rev-list --max-parents=0 HEAD)}...${GITHUB_REF_NAME}
|
|
|
|
**Changes**:
|
|
$log
|
|
EOF
|
|
echo "Generated release notes"
|
|
|
|
- name: Create Gitea release + upload assets
|
|
env:
|
|
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
GITEA_SERVER: ${{ github.server_url }}
|
|
REPO: ${{ github.repository }}
|
|
TAG: ${{ github.ref_name }}
|
|
run: |
|
|
set -euo pipefail
|
|
if [ -z "${RELEASE_TOKEN:-}" ]; then
|
|
echo "::error::RELEASE_TOKEN secret is not set"
|
|
exit 1
|
|
fi
|
|
echo "Releasing $TAG to $GITEA_SERVER/$REPO"
|
|
|
|
# Check if a release for this tag already exists (idempotency).
|
|
release_id=""
|
|
existing=$(curl --fail --silent --show-error -o /dev/null -w "%{http_code}" \
|
|
-H "Authorization: token $RELEASE_TOKEN" \
|
|
"$GITEA_SERVER/api/v1/repos/$REPO/releases/tags/$TAG" \
|
|
2>/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/<artifact-name>/<file>), 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."
|