From b603c7d4a9b69306ff26f671e04379a182088ed7 Mon Sep 17 00:00:00 2001 From: Nikolay Govorov Date: Thu, 19 Mar 2026 20:26:34 +0000 Subject: Migrate CI to forgejo --- .forgejo/workflows/build.yml | 212 +++++++++++++++++++++++++++ .github/workflows/build.yml | 208 -------------------------- .github/workflows/cla.yml | 30 ---- Cargo.toml | 2 +- README.md | 10 +- crates/recluse/src/controller_web.rs | 4 +- 6 files changed, 220 insertions(+), 246 deletions(-) create mode 100644 .forgejo/workflows/build.yml delete mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/cla.yml diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml new file mode 100644 index 0000000..5375edb --- /dev/null +++ b/.forgejo/workflows/build.yml @@ -0,0 +1,212 @@ +# 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: dev + +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}~dev.$(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 dev 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 Github Release + - name: Update 'dev' tag + run: | + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + + git tag -f ${{ env.RELEASE_TAG }} + git push origin --force tag ${{ env.RELEASE_TAG }} + - name: Delete old release assets + run: | + for asset in $(gh release view ${{ env.RELEASE_TAG }} --json assets --jq '.assets[].name' 2>/dev/null || true); do + gh release delete-asset ${{ env.RELEASE_TAG }} "$asset" --yes + done + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Create GitHub Release + uses: https://github.com/softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 + with: + name: ${{ env.RELEASE_TAG }} + tag_name: ${{ env.RELEASE_TAG }} + files: dist/* + body: | + Last successful build from `main` branch. + + **Release checks**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Update APT/RPM repos on s3 + - name: Create APT repository + run: | + aptly repo create -distribution=dev -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/ + 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 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index e21f530..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,208 +0,0 @@ -# SPDX-FileCopyrightText: 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: dev - -jobs: - lint: - name: Static checks - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - - - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 - - - name: Check licenses - uses: fsfe/reuse-action@676e2d560c9a403aa252096d99fcab3e1132b0f5 # v6.0.0 - - - name: Check dependencies - uses: EmbarkStudios/cargo-deny-action@3fd3802e88374d3fe9159b834c7714ec57d6c979 # 0.19.0 - - - 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: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - with: - components: llvm-tools-preview - - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 - - - name: Import GPG key - uses: 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}~dev.$(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: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - with: - name: coverage-lcov-${{ matrix.arch }} - path: coverage.lcov - - - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 - 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: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 - - - name: Run smoke tests against local instance - run: ./tests/smoke/run-local.sh - - publish: - name: Publish dev build - runs-on: ubuntu-latest - 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: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 - with: - pattern: packages-* - path: dist - merge-multiple: true - - # Configure GPG keys - - name: Import GPG key - uses: 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 Github Release - - name: Update 'dev' tag - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - - git tag -f ${{ env.RELEASE_TAG }} - git push origin --force tag ${{ env.RELEASE_TAG }} - - name: Delete old release assets - run: | - for asset in $(gh release view ${{ env.RELEASE_TAG }} --json assets --jq '.assets[].name' 2>/dev/null || true); do - gh release delete-asset ${{ env.RELEASE_TAG }} "$asset" --yes - done - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Create GitHub Release - uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0 - with: - name: ${{ env.RELEASE_TAG }} - tag_name: ${{ env.RELEASE_TAG }} - files: dist/* - body: | - Last successful build from `main` branch. - - **Release checks**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - # Update APT/RPM repos on s3 - - name: Create APT repository - run: | - aptly repo create -distribution=dev -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/ - 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 diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml deleted file mode 100644 index 9430337..0000000 --- a/.github/workflows/cla.yml +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nikolay Govorov -# SPDX-License-Identifier: AGPL-3.0-or-later - -name: "CLA Assistant" - -on: - issue_comment: - types: [created] - pull_request_target: - types: [opened, closed, synchronize] - -jobs: - CLAAssistant: - runs-on: ubuntu-latest - permissions: - actions: write - contents: write - statuses: write - pull-requests: write - steps: - - name: "CLA Assistant" - if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' - uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - branch: "main" - allowlist: mrdimidium - path-to-signatures: "LICENSES/cla.json" - path-to-document: "https://github.com/mrdimidium/recluse/blob/main/CLA.md" diff --git a/Cargo.toml b/Cargo.toml index 7b1d537..a074525 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ version = "0.1.0" license = "AGPL-3.0-or-later" authors = ["Nikolay Govorov "] homepage = "https://pkg.earth" -repository = "https://github.com/mrdimidium/recluse" +repository = "https://codeberg.org/mrdimidium/recluse" [workspace.dependencies] # local dependencies diff --git a/README.md b/README.md index ff9ac52..190607f 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ is **not** intended for production use. ```bash sudo apt install curl gnupg -curl -fsSL https://github.com/mrdimidium/recluse/releases/download/dev/public.gpg | sudo gpg --dearmor -o /usr/share/keyrings/recluse.gpg -echo "deb [signed-by=/usr/share/keyrings/recluse.gpg] https://recluse.hel1.your-objectstorage.com/apt/ dev main" | sudo tee /etc/apt/sources.list.d/recluse.list +curl -fsSL https://codeberg.org/mrdimidium/recluse/releases/download/dev/public.gpg | sudo gpg --dearmor -o /usr/share/keyrings/recluse.gpg +echo "deb [signed-by=/usr/share/keyrings/recluse.gpg] https://dimidiumlabs.fsn1.your-objectstorage.com/apt/ dev main" | sudo tee /etc/apt/sources.list.d/recluse.list sudo apt update && sudo apt install recluse sudo systemctl enable --now recluse @@ -23,8 +23,8 @@ sudo systemctl enable --now recluse **Fedora/RedHat:** ```bash -sudo rpm --import https://github.com/mrdimidium/recluse/releases/download/dev/public.gpg -sudo dnf config-manager --add-repo https://recluse.hel1.your-objectstorage.com/rpm/ +sudo rpm --import https://codeberg.org/mrdimidium/recluse/releases/download/dev/public.gpg +sudo dnf config-manager --add-repo https://dimidiumlabs.fsn1.your-objectstorage.com/rpm/ sudo dnf install recluse sudo systemctl enable --now recluse @@ -35,7 +35,7 @@ sudo systemctl enable --now recluse 1. Install build dependencies: - Fedora/RedHat: `sudo dnf install gcc openssl-devel pkg-config` - Debian/Ubuntu: `sudo apt install build-essential libssl-dev pkg-config` -1. Clone repo: `git clone https://github.com/mrdimidium/recluse.git && cd recluse` +1. Clone repo: `git clone https://codeberg.org/mrdimidium/recluse.git && cd recluse` 1. Build from source: `cargo build --release` 1. Install manually diff --git a/crates/recluse/src/controller_web.rs b/crates/recluse/src/controller_web.rs index 6d4d176..83c4931 100644 --- a/crates/recluse/src/controller_web.rs +++ b/crates/recluse/src/controller_web.rs @@ -178,7 +178,7 @@ impl WebController { p { "Recluse is open source software licensed under " a href="https://www.gnu.org/licenses/agpl-3.0.html" { "AGPL-3.0" } ". " - "Source code is available on " a href="https://github.com/mrdimidium/recluse" { "GitHub" } ". " + "Source code is available on " a href="https://codeberg.org/mrdimidium/recluse" { "Codeberg" } ". " "A list of dependency licenses " a href="/about/licenses" { "is available" } "." } @@ -335,7 +335,7 @@ impl WebController { p { "Source code is available on " - a href="https://github.com/mrdimidium/recluse" { "GitHub" } + a href="https://codeberg.org/mrdimidium/recluse" { "Codeberg" } ". The full license text is included below." } -- Gilti