aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '.forgejo/workflows/build.yml')
-rw-r--r--.forgejo/workflows/build.yml238+238 −0
1 files changed, 238 insertions, 0 deletions
diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml
new file mode 100644
--- /dev/null
+++ b/.forgejo/workflows/build.yml
@@ -0,0 +1,238 @@
+# Copyright (c) 2026 Nikolay Govorov
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+name: Build
+
+on:
+ push:
+ branches: [main]
+ tags: ["v*"]
+ pull_request:
+ branches: [main]
+
+env:
+ CARGO_TERM_COLOR: always
+ RELEASE_TAG: nightly
+
+jobs:
+ lint:
+ name: Static checks
+ runs-on: ubuntu-24.04
+ steps:
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+
+ - uses: https://github.com/dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
+ with:
+ components: clippy,rustfmt
+ - uses: https://github.com/Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
+
+ - name: Check licenses
+ uses: https://github.com/fsfe/reuse-action@676e2d560c9a403aa252096d99fcab3e1132b0f5 # v6.0.0
+
+ - name: Check dependencies
+ run: |
+ cargo install --locked cargo-deny
+ cargo deny check
+
+ - name: Check formatting
+ run: cargo fmt --all --check
+
+ - name: Run clippy
+ run: cargo clippy --all-targets --all-features -- -D warnings
+
+ build:
+ name: Build (${{ matrix.arch }})
+ runs-on: ${{ matrix.runner }}
+ needs: [lint]
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - runner: ubuntu-24.04
+ arch: amd64
+ # - runner: ubuntu-24.04-arm
+ # arch: arm64
+ steps:
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+
+ - uses: https://github.com/dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
+ with:
+ components: llvm-tools-preview
+ - uses: https://github.com/Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
+
+ - name: Import GPG key
+ uses: https://github.com/crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec #v6.3.0
+ with:
+ passphrase: ${{ secrets.GPG_PASSPHRASE }}
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+
+ - run: cargo build --release
+ - run: cargo test --all-features --release --locked
+
+ - name: Install nfpm
+ run: |
+ echo 'deb [trusted=yes] https://repo.goreleaser.com/apt/ /' | sudo tee /etc/apt/sources.list.d/goreleaser.list
+ sudo apt update && sudo apt install nfpm
+
+ - name: Build packages
+ run: |
+ export SIGNING_PRIVATE_KEY="/tmp/private.asc"
+ printf '%s' "$GPG_PRIVATE_KEY" > $SIGNING_PRIVATE_KEY
+ chmod 600 $SIGNING_PRIVATE_KEY
+
+ PKG_VERSION=$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[] | select(.name == "recluse") | .version')
+ export VERSION="${PKG_VERSION}~nightly.$(git log -1 --format=%ct)"
+ export ARCH=${{ matrix.arch }}
+
+ mkdir -p dist/
+ for pkg in deb rpm; do
+ nfpm package --packager $pkg --target dist/
+ done
+ env:
+ GPG_KEY_ID: ${{ vars.GPG_KEY_ID }}
+ GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
+ NFPM_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+
+ - name: Install tools
+ run: make setup
+
+ - name: Generate coverage (lcov)
+ run: cargo llvm-cov --all-features --workspace --lcov --output-path coverage.lcov
+
+ - name: Upload coverage artifact
+ uses: https://code.forgejo.org/forgejo/upload-artifact@cb8afe72b42edc798abfb8fcb556cf660d894245 # v5
+ with:
+ name: coverage-lcov-${{ matrix.arch }}
+ path: coverage.lcov
+
+ - uses: https://code.forgejo.org/forgejo/upload-artifact@cb8afe72b42edc798abfb8fcb556cf660d894245 # v5
+ with:
+ name: packages-${{ matrix.arch }}
+ path: dist/*
+
+ smoke:
+ name: Smoke tests
+ runs-on: ubuntu-24.04
+ needs: [build]
+ if: github.ref == 'refs/heads/main'
+ steps:
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+
+ - uses: https://github.com/dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
+ - uses: https://github.com/Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2
+
+ - name: Run smoke tests against local instance
+ run: ./tests/smoke/run-local.sh
+
+ publish:
+ name: Publish nightly build
+ runs-on: ubuntu-24.04
+ needs: [build, smoke]
+ if: github.ref == 'refs/heads/main'
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+ - name: Install tools
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y aptly rclone createrepo-c
+
+ - uses: https://code.forgejo.org/forgejo/download-artifact@1314311ddb542af343a82d478ac786ceada4143a # v5
+ with:
+ pattern: packages-*
+ path: dist
+ merge-multiple: true
+
+ # Configure GPG keys
+ - name: Import GPG key
+ uses: https://github.com/crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec #v6.3.0
+ with:
+ passphrase: ${{ secrets.GPG_PASSPHRASE }}
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+ - name: Export GPG public key
+ run: printf '%s' "$GPG_PUBLIC_KEY" > dist/public.gpg
+ env:
+ GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }}
+
+ # Update Forgejo Release
+ - name: Update nightly tag
+ run: |
+ git config user.name "forgejo-actions[bot]"
+ git config user.email "forgejo-actions[bot]@noreply.codeberg.org"
+
+ git tag -f ${{ env.RELEASE_TAG }}
+ git push origin --force tag ${{ env.RELEASE_TAG }}
+
+ - name: Update Forgejo release
+ run: |
+ call() {
+ curl -sS -X "$1" \
+ -H "Content-Type: $2" \
+ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
+ "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases$3" \
+ "${@:4}";
+ }
+
+ # Delete existing release
+ RELEASE_ID=$(call GET "" "/tags/${{ env.RELEASE_TAG }}" | jq -r '.id // empty')
+ if [ -n "$RELEASE_ID" ]; then
+ call DELETE "" "/$RELEASE_ID"
+ fi
+
+ # Create release and upload assets
+ RELEASE_ID=$(jq -n \
+ --arg name "${{ env.RELEASE_TAG }}" \
+ --arg body "${{ env.description }}" \
+ '{name: $name, tag_name: $name, body: $body}' \
+ | call POST application/json "/" -d @- | jq -r '.id')
+
+ for file in dist/*; do
+ call POST application/octet-stream "/$RELEASE_ID/assets?name=$(basename "$file")" \
+ --data-binary @"$file"
+ done
+ env:
+ description: |
+ Last successful build from `main` branch.
+
+ **Release checks**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}
+
+ # Update APT/RPM repos on s3
+ - name: Create APT repository
+ run: |
+ aptly repo create -distribution=nightly -component=main recluse
+ aptly repo add recluse dist/*.deb
+ aptly publish repo -architectures=amd64,arm64 -gpg-key="${{vars.GPG_KEY_ID}}" recluse
+
+ - name: Create RPM repository
+ run: |
+ mkdir -p rpm-repo
+ cp dist/*.rpm rpm-repo/
+
+ cat > rpm-repo/recluse-nightly.repo << EOF
+ [recluse-nightly]
+ name=Recluse Nightly
+ gpgkey=${{github.server_url}}/${{github.repository}}/releases/download/${{env.RELEASE_TAG}}/public.gpg
+ baseurl=https://${{vars.S3_BUCKET}}.${{vars.S3_ENDPOINT}}/rpm/
+ enabled=1
+ gpgcheck=1
+ EOF
+
+ createrepo_c rpm-repo/
+ gpg --default-key="${{vars.GPG_KEY_ID}}" --detach-sign --armor rpm-repo/repodata/repomd.xml
+
+ - name: Upload RPM to S3
+ run: |
+ mkdir -p ~/.config/rclone
+ cat > ~/.config/rclone/rclone.conf << EOF
+ [hetzner]
+ type = s3
+ provider = Other
+ acl = public-read
+ endpoint = ${{vars.S3_ENDPOINT}}
+ access_key_id = ${{secrets.S3_ACCESS_KEY_ID}}
+ secret_access_key = ${{secrets.S3_SECRET_ACCESS_KEY}}
+ EOF
+
+ rclone sync rpm-repo/ "hetzner:${{vars.S3_BUCKET}}/rpm/" --progress
+ rclone sync ~/.aptly/public/ "hetzner:${{vars.S3_BUCKET}}/apt/" --progress