diff --git a/.forgejo/workflows/ci-checks.yml b/.forgejo/workflows/ci-checks.yml new file mode 100644 index 00000000..86c927f5 --- /dev/null +++ b/.forgejo/workflows/ci-checks.yml @@ -0,0 +1,175 @@ +name: CI Checks + +on: + push: + pull_request: + +# Cancel in-progress runs when a new push is made to the same branch +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + fast-checks: + name: Prek & Format + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install uv + uses: https://github.com/astral-sh/setup-uv@v6 + with: + enable-cache: true + ignore-nothing-to-cache: true + cache-dependency-glob: '' + + - name: Run prek (formerly prefligit) + run: uvx prek run --show-diff-on-failure --color=always -v --all-files --hook-stage manual + + - name: Install rust nightly with rustfmt + run: | + uvx rustup override set nightly + uvx rustup component add rustfmt + + - name: Check formatting + run: | + cargo +nightly fmt --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install uv + uses: https://github.com/astral-sh/setup-uv@v6 + with: + enable-cache: true + ignore-nothing-to-cache: true + cache-dependency-glob: '' # Disable Python dependency tracking for Rust project + + - name: Install Rust toolchain + run: | + # Install toolchain from rust-toolchain.toml + uvx rustup show # This will auto-install from rust-toolchain.toml + + # cache-apt-pkgs-action requires apt lists to be initialised first + - name: Update APT package lists + run: sudo apt-get update + + - name: Cache system packages + uses: https://github.com/awalsh128/cache-apt-pkgs-action@latest + with: + packages: clang liburing-dev + version: 1.0 + + - name: Cache Rust registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/git + !~/.cargo/git/checkouts + ~/.cargo/registry + !~/.cargo/registry/src + key: rust-registry-${{hashFiles('**/Cargo.lock') }} + + - name: Run Clippy lints + run: | + cargo clippy \ + --workspace \ + --features full \ + --locked \ + --no-deps \ + --profile test \ + -- \ + -D warnings + + tests: + name: Tests + runs-on: ubuntu-latest + env: + SCCACHE_ENABLED: ${{ vars.GH_APP_ID != '' && secrets.GH_APP_PRIVATE_KEY != '' }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install uv + uses: https://github.com/astral-sh/setup-uv@v6 + with: + enable-cache: true + ignore-nothing-to-cache: true + cache-dependency-glob: '' # Disable Python dependency tracking for Rust project + + - name: Install Rust toolchain + run: | + # Install toolchain from rust-toolchain.toml + uvx rustup show # This will auto-install from rust-toolchain.toml + + # cache-apt-pkgs-action requires apt lists to be initialised first + - name: Update APT package lists + run: sudo apt-get update + + - name: Cache system packages + uses: https://github.com/awalsh128/cache-apt-pkgs-action@latest + with: + packages: clang liburing-dev + version: 1.0 + + - name: Cache Rust registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/git + !~/.cargo/git/checkouts + ~/.cargo/registry + !~/.cargo/registry/src + key: rust-registry-${{hashFiles('**/Cargo.lock') }} + + - name: Create GitHub App token for sccache + if: env.SCCACHE_ENABLED == 'true' + uses: https://github.com/actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.GH_APP_ID }} + private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} + github-api-url: https://api.github.com + owner: ${{ vars.GH_APP_OWNER }} + repositories: "" + + - name: Setup sccache + if: env.SCCACHE_ENABLED == 'true' + uses: ./.forgejo/actions/sccache + with: + token: ${{ steps.app-token.outputs.token }} + + - name: Setup Timelord + if: env.SCCACHE_ENABLED == 'true' + uses: ./.forgejo/actions/timelord + with: + key: sccache-v0 + path: . + + - name: Run Cargo tests + run: | + cargo test \ + --workspace \ + --features full \ + --locked \ + --profile test \ + --all-targets \ + --no-fail-fast + + - name: Display sccache statistics + if: always() && env.SCCACHE_ENABLED == 'true' + run: sccache --show-stats diff --git a/.forgejo/workflows/documentation.yml b/.forgejo/workflows/deploy-docs.yml similarity index 100% rename from .forgejo/workflows/documentation.yml rename to .forgejo/workflows/deploy-docs.yml diff --git a/.forgejo/workflows/element.yml b/.forgejo/workflows/deploy-element.yml similarity index 100% rename from .forgejo/workflows/element.yml rename to .forgejo/workflows/deploy-element.yml diff --git a/.forgejo/workflows/mirror-images.yml b/.forgejo/workflows/docker-mirror.yml similarity index 100% rename from .forgejo/workflows/mirror-images.yml rename to .forgejo/workflows/docker-mirror.yml diff --git a/.forgejo/workflows/prefligit-checks.yml b/.forgejo/workflows/prefligit-checks.yml deleted file mode 100644 index cc512496..00000000 --- a/.forgejo/workflows/prefligit-checks.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Checks / Prefligit - -on: - push: - pull_request: -permissions: - contents: read - -jobs: - prefligit: - runs-on: ubuntu-latest - env: - FROM_REF: ${{ github.event.pull_request.base.sha || (!github.event.forced && ( github.event.before != '0000000000000000000000000000000000000000' && github.event.before || github.sha )) || format('{0}~', github.sha) }} - TO_REF: ${{ github.sha }} - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - persist-credentials: false - - uses: ./.forgejo/actions/prefligit - with: - extra_args: --all-files --hook-stage manual diff --git a/.forgejo/workflows/release-image.yml b/.forgejo/workflows/release-builds.yml similarity index 76% rename from .forgejo/workflows/release-image.yml rename to .forgejo/workflows/release-builds.yml index 04fc9de9..ec193e4e 100644 --- a/.forgejo/workflows/release-image.yml +++ b/.forgejo/workflows/release-builds.yml @@ -1,6 +1,8 @@ -name: Release Docker Image +name: Release Builds +# Cancel in-progress runs when a new push is made to the same branch concurrency: - group: "release-image-${{ github.ref }}" + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false # Don't cancel release builds on: push: @@ -21,7 +23,8 @@ env: BUILTIN_REGISTRY_ENABLED: "${{ ((vars.BUILTIN_REGISTRY_USER && secrets.BUILTIN_REGISTRY_PASSWORD) || (github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false)) && 'true' || 'false' }}" jobs: - define-variables: + prepare: + name: Prepare Build Matrix runs-on: ubuntu-latest outputs: @@ -30,7 +33,7 @@ jobs: build_matrix: ${{ steps.var.outputs.build_matrix }} steps: - - name: Setting variables + - name: Define build matrix and registries uses: https://github.com/actions/github-script@v7 id: var with: @@ -56,9 +59,10 @@ jobs: }}) })) - build-image: + build: + name: Build Images & Binaries runs-on: dind - needs: define-variables + needs: prepare permissions: contents: read packages: write @@ -78,16 +82,16 @@ jobs: } steps: - - name: Echo strategy - run: echo '${{ toJSON(fromJSON(needs.define-variables.outputs.build_matrix)) }}' - - name: Echo matrix - run: echo '${{ toJSON(matrix) }}' + - name: Display build matrix + run: | + echo "Strategy: ${{ toJSON(fromJSON(needs.prepare.outputs.build_matrix)) }}" + echo "Matrix: ${{ toJSON(matrix) }}" - name: Checkout repository uses: actions/checkout@v4 with: persist-credentials: false - - name: Install rust + - name: Install Rust toolchain id: rust-toolchain uses: ./.forgejo/actions/rust-toolchain @@ -95,34 +99,28 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v3 - # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - - name: Login to builtin registry + - name: Login to container registry uses: docker/login-action@v3 with: registry: ${{ env.BUILTIN_REGISTRY }} username: ${{ vars.BUILTIN_REGISTRY_USER || github.actor }} password: ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }} - # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. - - name: Extract metadata (labels, annotations) for Docker + - name: Extract Docker metadata id: meta uses: docker/metadata-action@v5 with: - images: ${{needs.define-variables.outputs.images}} + images: ${{needs.prepare.outputs.images}} # default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509 env: DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index - # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. - # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. - # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. - # It will not push images generated from a pull request - - name: Get short git commit SHA + - name: Get commit SHA id: sha run: | calculatedSha=$(git rev-parse --short ${{ github.sha }}) echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV - - name: Get Git commit timestamps + - name: Get commit timestamp run: echo "TIMESTAMP=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV - uses: ./.forgejo/actions/timelord @@ -160,7 +158,7 @@ jobs: path: | var-lib-apt-${{ matrix.slug }} key: var-lib-apt-${{ matrix.slug }} - - name: inject cache into docker + - name: Inject build cache uses: https://github.com/reproducible-containers/buildkit-cache-dance@v3.1.0 with: cache-map: | @@ -176,7 +174,7 @@ jobs: } skip-extraction: ${{ steps.cache.outputs.cache-hit }} - - name: Build and push Docker image by digest + - name: Build Docker image id: build uses: docker/build-push-action@v6 with: @@ -193,26 +191,25 @@ jobs: cache-from: type=gha # cache-to: type=gha,mode=max sbom: true - outputs: type=image,"name=${{ needs.define-variables.outputs.images_list }}",push-by-digest=true,name-canonical=true,push=true + outputs: type=image,"name=${{ needs.prepare.outputs.images_list }}",push-by-digest=true,name-canonical=true,push=true env: SOURCE_DATE_EPOCH: ${{ env.TIMESTAMP }} - # For publishing multi-platform manifests - - name: Export digest + - name: Export image digest run: | mkdir -p /tmp/digests digest="${{ steps.build.outputs.digest }}" touch "/tmp/digests/${digest#sha256:}" - - name: Extract binary from container (image) + - name: Create container from image id: extract-binary-image run: | mkdir -p /tmp/binaries digest="${{ steps.build.outputs.digest }}" - echo "container_id=$(docker create --platform ${{ matrix.platform }} ${{ needs.define-variables.outputs.images_list }}@$digest)" >> $GITHUB_OUTPUT - - name: Extract binary from container (copy) + echo "container_id=$(docker create --platform ${{ matrix.platform }} ${{ needs.prepare.outputs.images_list }}@$digest)" >> $GITHUB_OUTPUT + - name: Extract binary from container run: docker cp ${{ steps.extract-binary-image.outputs.container_id }}:/sbin/conduwuit /tmp/binaries/conduwuit-${{ matrix.target_cpu }}-${{ matrix.slug }}-${{ matrix.profile }} - - name: Extract binary from container (cleanup) + - name: Clean up container run: docker rm ${{ steps.extract-binary-image.outputs.container_id }} - name: Upload binary artifact @@ -230,9 +227,10 @@ jobs: if-no-files-found: error retention-days: 5 - merge: + publish: + name: Publish Multi-platform Manifest runs-on: dind - needs: [define-variables, build-image] + needs: [prepare, build] steps: - name: Download digests uses: forgejo/download-artifact@v4 @@ -240,8 +238,7 @@ jobs: path: /tmp/digests pattern: digests-* merge-multiple: true - # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - - name: Login to builtin registry + - name: Login to container registry uses: docker/login-action@v3 with: registry: ${{ env.BUILTIN_REGISTRY }} @@ -251,7 +248,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Extract metadata (tags) for Docker + - name: Extract Docker tags id: meta uses: docker/metadata-action@v5 with: @@ -263,15 +260,15 @@ jobs: type=ref,event=pr type=sha,format=long type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} - images: ${{needs.define-variables.outputs.images}} + images: ${{needs.prepare.outputs.images}} # default labels & annotations: https://github.com/docker/metadata-action/blob/master/src/meta.ts#L509 env: DOCKER_METADATA_ANNOTATIONS_LEVELS: index - - name: Create manifest list and push + - name: Create and push manifest working-directory: /tmp/digests env: - IMAGES: ${{needs.define-variables.outputs.images}} + IMAGES: ${{needs.prepare.outputs.images}} shell: bash run: | IFS=$'\n' @@ -287,7 +284,7 @@ jobs: - name: Inspect image env: - IMAGES: ${{needs.define-variables.outputs.images}} + IMAGES: ${{needs.prepare.outputs.images}} shell: bash run: | IMAGES_LIST=($IMAGES) diff --git a/.forgejo/workflows/renovate.yml b/.forgejo/workflows/renovate.yml new file mode 100644 index 00000000..87ea87e7 --- /dev/null +++ b/.forgejo/workflows/renovate.yml @@ -0,0 +1,64 @@ +name: Renovate +on: + schedule: + # Run at 2am UTC daily + - cron: '0 2 * * *' + workflow_dispatch: + inputs: + dryRun: + description: 'Dry run mode' + required: false + default: 'false' + type: choice + options: + - 'true' + - 'false' + logLevel: + description: 'Log level' + required: false + default: 'info' + type: choice + options: + - 'debug' + - 'info' + - 'warn' + - 'error' + push: + branches: + - main + paths: + - '.forgejo/workflows/renovate.yml' + - 'renovate.json' + +jobs: + renovate: + name: Renovate + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run Renovate + uses: renovatebot/github-action@v40.1.0 + with: + token: ${{ secrets.RENOVATE_TOKEN }} + configurationFile: renovate.json + env: + # Platform settings + RENOVATE_PLATFORM: gitea + RENOVATE_ENDPOINT: ${{ github.server_url }}/api/v1 + RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} + + # Repository settings + RENOVATE_REPOSITORIES: '["${{ github.repository }}"]' + + # Behaviour settings + RENOVATE_DRY_RUN: ${{ inputs.dryRun || 'false' }} + LOG_LEVEL: ${{ inputs.logLevel || 'info' }} + + # Forgejo/Gitea specific + RENOVATE_GIT_AUTHOR: 'Renovate Bot ' + + # PR settings + RENOVATE_PR_HOURLY_LIMIT: '2' + RENOVATE_PR_CONCURRENT_LIMIT: '3' diff --git a/.forgejo/workflows/rust-checks.yml b/.forgejo/workflows/rust-checks.yml deleted file mode 100644 index c46363a0..00000000 --- a/.forgejo/workflows/rust-checks.yml +++ /dev/null @@ -1,144 +0,0 @@ -name: Checks / Rust - -on: - push: - -jobs: - format: - name: Format - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - persist-credentials: false - - - name: Install rust - uses: ./.forgejo/actions/rust-toolchain - with: - toolchain: "nightly" - components: "rustfmt" - - - name: Check formatting - run: | - cargo +nightly fmt --all -- --check - - clippy: - name: Clippy - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - persist-credentials: false - - - name: Install rust - uses: ./.forgejo/actions/rust-toolchain - - - uses: https://github.com/actions/create-github-app-token@v2 - id: app-token - with: - app-id: ${{ vars.GH_APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - github-api-url: https://api.github.com - owner: ${{ vars.GH_APP_OWNER }} - repositories: "" - - name: Install sccache - uses: ./.forgejo/actions/sccache - with: - token: ${{ steps.app-token.outputs.token }} - - run: sudo apt-get update - - name: Install system dependencies - uses: https://github.com/awalsh128/cache-apt-pkgs-action@v1 - with: - packages: clang liburing-dev - version: 1 - - name: Cache Rust registry - uses: actions/cache@v3 - with: - path: | - ~/.cargo/git - !~/.cargo/git/checkouts - ~/.cargo/registry - !~/.cargo/registry/src - key: rust-registry-${{hashFiles('**/Cargo.lock') }} - - name: Timelord - uses: ./.forgejo/actions/timelord - with: - key: sccache-v0 - path: . - - name: Clippy - run: | - cargo clippy \ - --workspace \ - --features full \ - --locked \ - --no-deps \ - --profile test \ - -- \ - -D warnings - - - name: Show sccache stats - if: always() - run: sccache --show-stats - - cargo-test: - name: Cargo Test - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - persist-credentials: false - - - name: Install rust - uses: ./.forgejo/actions/rust-toolchain - - - uses: https://github.com/actions/create-github-app-token@v2 - id: app-token - with: - app-id: ${{ vars.GH_APP_ID }} - private-key: ${{ secrets.GH_APP_PRIVATE_KEY }} - github-api-url: https://api.github.com - owner: ${{ vars.GH_APP_OWNER }} - repositories: "" - - name: Install sccache - uses: ./.forgejo/actions/sccache - with: - token: ${{ steps.app-token.outputs.token }} - - run: sudo apt-get update - - name: Install system dependencies - uses: https://github.com/awalsh128/cache-apt-pkgs-action@v1 - with: - packages: clang liburing-dev - version: 1 - - name: Cache Rust registry - uses: actions/cache@v3 - with: - path: | - ~/.cargo/git - !~/.cargo/git/checkouts - ~/.cargo/registry - !~/.cargo/registry/src - key: rust-registry-${{hashFiles('**/Cargo.lock') }} - - name: Timelord - uses: ./.forgejo/actions/timelord - with: - key: sccache-v0 - path: . - - name: Cargo Test - run: | - cargo test \ - --workspace \ - --features full \ - --locked \ - --profile test \ - --all-targets \ - --no-fail-fast - - - name: Show sccache stats - if: always() - run: sccache --show-stats diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 68e3a982..da594310 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - - id: check-byte-order-marker + - id: fix-byte-order-marker - id: check-case-conflict - id: check-symlinks - id: destroyed-symlinks diff --git a/renovate.json b/renovate.json index eecf8532..c41d5f99 100644 --- a/renovate.json +++ b/renovate.json @@ -22,5 +22,24 @@ "tikv-jemalloc-ctl", "opentelemetry-rust", "tracing-opentelemetry" - ] + ], + "github-actions": { + "enabled": true, + "fileMatch": [ + "(^|/)\\.forgejo/workflows/[^/]+\\.ya?ml$", + "(^|/)\\.forgejo/actions/[^/]+/action\\.ya?ml$", + "(^|/)\\.github/workflows/[^/]+\\.ya?ml$", + "(^|/)\\.github/actions/[^/]+/action\\.ya?ml$" + ] + }, + "packageRules": [ + { + "description": "Group all non-major GitHub Actions updates", + "matchManagers": ["github-actions"], + "matchUpdateTypes": ["minor", "patch"], + "groupName": "github-actions-non-major" + } + ], + "prConcurrentLimit": 3, + "prHourlyLimit": 2 }