diff options
Diffstat (limited to '.forgejo/workflows/build.yml')
| -rw-r--r-- | .forgejo/workflows/build.yml | 238 | +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 |
