Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 80 additions & 66 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
name: Quality

on:
workflow_call:
pull_request:
push:
branches:
- main

concurrency:
group: quality-${{ github.workflow }}-${{ github.ref }}
Expand All @@ -19,21 +17,6 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 20

services:
postgres:
image: postgres:17
env:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres -d postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- name: Checkout repository
uses: actions/checkout@v6
Expand Down Expand Up @@ -84,39 +67,15 @@ jobs:

- name: Test Rust workspace
run: just test rust
env:
GRASS_TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres

- name: Test PostgreSQL deployment lifecycle regressions
run: |
cargo test -p grass-control-api domain::delivery::tests::postgres_ -- --ignored
cargo test -p grass-control-api domain::node_deletions::tests::postgres_ -- --ignored
env:
GRASS_TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres

- name: Test Console workspace
run: just test console

- name: Apply migrations to the disposable CI database
run: cargo run -p grass-control-api -- --config "$RUNNER_TEMP/grass-migration.toml" migrate
env:
GWAPI_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres

- name: Verify certificate database columns and constraints
run: >-
cargo test -p grass-control-api
infra::database::migration::m20260910_000032_managed_certificates::tests::managed_certificate_schema_matches_signed_lifecycle_and_ack_protocol
-- --ignored --exact
env:
GRASS_TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
- name: Verify embedded Console asset rebuilds
run: just assets-check

- name: Verify regional ingress migration upgrade and rollback
run: >-
cargo test -p grass-control-api
infra::database::migrate::tests::postgres_regional_ingress_schema_matches_domain_and_is_reversible
-- --ignored --exact
env:
GRASS_TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
- name: Verify release metadata policy
run: just release-check

- name: Check project license metadata
run: just license-check
Expand Down Expand Up @@ -163,31 +122,86 @@ jobs:
GRASS_NODE_SMOKE_IMAGE: grass-build:smoke
GRASS_NODE_SMOKE_SOCKET: unix:///var/run/docker.sock

release-images:
name: Release images
runs-on: ubuntu-latest
timeout-minutes: 45
msrv:
name: Rust MSRV (${{ matrix.runner }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
runner: [ubuntu-latest, macos-latest]
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Install cargo-msrv
uses: taiki-e/install-action@v2
with:
tool: cargo-msrv@0.18.4

- name: Cache minimum-version build output
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-msrv-${{ hashFiles('Cargo.toml', 'Cargo.lock') }}

- name: Verify the workspace minimum Rust version
run: cargo msrv verify --manifest-path apps/control-api/Cargo.toml --no-log -- cargo check --workspace --all-targets --locked

service-regressions:
name: PostgreSQL and Redis regressions
runs-on: ubuntu-latest
timeout-minutes: 30
services:
postgres:
image: postgres:17
env:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U postgres -d postgres"
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Build release runtime variants
uses: docker/bake-action@v6
- name: Install Just
uses: extractions/setup-just@v4

- name: Cache service regression build output
uses: actions/cache@v5
with:
files: docker-bake.hcl
load: true
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-services-${{ hashFiles('Cargo.lock') }}

- name: Run complete PostgreSQL and Redis regressions
run: just test-services
env:
TAGS_DEBIAN: grass-worker:ci-debian
TAGS_SLIM: grass-worker:ci-slim
TAGS_ALPINE: grass-worker:ci-alpine

- name: Check packaged binaries
run: |
for variant in debian slim alpine; do
docker run --rm --network none "grass-worker:ci-${variant}" grass-control-api --version
docker run --rm --network none "grass-worker:ci-${variant}" grass-node --version
done
GRASS_TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres
GRASS_TEST_REDIS_URL: redis://localhost:6379/0
84 changes: 65 additions & 19 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,31 @@ concurrency:
cancel-in-progress: false

jobs:
validation:
name: Validate release commit
uses: ./.github/workflows/quality.yml
permissions:
contents: read

metadata:
name: Validate release metadata
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
docker_tags: ${{ steps.policy.outputs.docker_tags }}
prerelease: ${{ steps.policy.outputs.prerelease }}
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Derive branch or version policy
id: policy
run: python3 scripts/release-metadata.py

docker:
name: Docker image
needs: [validation, metadata]
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
Expand All @@ -43,35 +66,28 @@ jobs:
uses: docker/metadata-action@v5
with:
images: ${{ env.RUNTIME_IMAGE }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
flavor: latest=false
tags: ${{ needs.metadata.outputs.docker_tags }}

- name: Derive Slim image metadata
id: meta-slim
uses: docker/metadata-action@v5
with:
images: ${{ env.RUNTIME_IMAGE }}
flavor: suffix=-slim
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
flavor: |
latest=false
suffix=-slim
tags: ${{ needs.metadata.outputs.docker_tags }}

- name: Derive Alpine image metadata
id: meta-alpine
uses: docker/metadata-action@v5
with:
images: ${{ env.RUNTIME_IMAGE }}
flavor: suffix=-alpine
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
flavor: |
latest=false
suffix=-alpine
tags: ${{ needs.metadata.outputs.docker_tags }}

- name: Prepare Bake labels
id: bake-labels
Expand All @@ -84,7 +100,34 @@ jobs:
echo EOF
} >> "$GITHUB_OUTPUT"

- name: Build and push runtime variants
- name: Build release runtime variants for verification
uses: docker/bake-action@v6
with:
files: docker-bake.hcl
load: true
env:
IMAGE: ${{ env.RUNTIME_IMAGE }}
TAGS_DEBIAN: ${{ steps.meta.outputs.tags }}
TAGS_SLIM: ${{ steps.meta-slim.outputs.tags }}
TAGS_ALPINE: ${{ steps.meta-alpine.outputs.tags }}
LABELS_JSON: ${{ steps.bake-labels.outputs.labels_json }}

- name: Check packaged binaries in every runtime variant
shell: bash
env:
TAGS_DEBIAN: ${{ steps.meta.outputs.tags }}
TAGS_SLIM: ${{ steps.meta-slim.outputs.tags }}
TAGS_ALPINE: ${{ steps.meta-alpine.outputs.tags }}
run: |
for tags in "$TAGS_DEBIAN" "$TAGS_SLIM" "$TAGS_ALPINE"; do
image_ref="${tags%%$'\n'*}"
test -n "$image_ref"
docker run --rm --pull=never --network none "$image_ref" grass-control-api --version
docker run --rm --pull=never --network none "$image_ref" grass-node --version
done

# Reuse the verified build cache and retain BuildKit publication metadata.
- name: Publish verified runtime variants
uses: docker/bake-action@v6
with:
files: docker-bake.hcl
Expand All @@ -98,6 +141,7 @@ jobs:

binaries:
name: Release binaries
needs: [validation, metadata]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ${{ matrix.runner }}
timeout-minutes: 60
Expand Down Expand Up @@ -141,7 +185,7 @@ jobs:
run: vp build

- name: Build release binaries
run: cargo build --release --target ${{ matrix.target }} -p grass-control-api -p grass-node
run: cargo build --release --locked --target ${{ matrix.target }} -p grass-control-api -p grass-node

- name: Package artifacts
run: |
Expand All @@ -155,3 +199,5 @@ jobs:
with:
files: dist/*.tar.gz
generate_release_notes: true
prerelease: ${{ needs.metadata.outputs.prerelease == 'true' }}
make_latest: ${{ needs.metadata.outputs.prerelease == 'true' && 'false' || 'true' }}
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ resolver = "3"
edition = "2024"
license = "BSD-3-Clause"
repository = "https://github.com/Grass-Development-Team/grass-worker"
rust-version = "1.85"
rust-version = "1.88"
version = "0.1.0"

[workspace.dependencies]
Expand Down
21 changes: 20 additions & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test target="all":
check target="all":
{{ if target == "rust" { "cargo check --workspace" } else if target == "console" { "cd " + console + " && vp check" } else if target == "all" { "cargo check --workspace && cd " + console + " && vp check" } else { error("unknown check target: " + target) } }}

quality: fmt clippy test check build license-check
quality: fmt clippy test check build assets-check release-check license-check

license-check:
test -f LICENSE
Expand All @@ -48,3 +48,22 @@ preview target="console":

migrate:
cargo run -p grass-control-api -- migrate

# Verify the locked workspace with its declared minimum supported Rust version.
msrv:
cargo msrv verify --manifest-path apps/control-api/Cargo.toml --no-log -- cargo check --workspace --all-targets --locked

# Build distributable binaries with the production Console embedded.
release:
cd {{ console }} && vp build
cargo build --release --locked -p grass-control-api -p grass-node

assets-check:
python3 scripts/check-embedded-assets.py

# This suite creates and removes test schemas in the configured disposable services.
test-services:
python3 scripts/test-services.py

release-check:
python3 -m unittest discover -s scripts -p "test_release_metadata.py"
Loading