Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
7572dfe
Update Mutexbot CLI flow to use DB - insert and loop only (without re…
Shugenya Sep 5, 2025
2e8c2b2
Replaced tokio postgres with sqlx.
Shugenya Sep 8, 2025
c9988d1
Renamed project to "Deploy queue".
Shugenya Sep 8, 2025
18c066c
Added DB schema.
Shugenya Sep 8, 2025
7212f4d
Changed results from tuples to struct.
Shugenya Sep 10, 2025
084417c
Removed test DB credentials
Shugenya Sep 10, 2025
b39cc40
Store the deployment_id as a GitHub output
Shugenya Sep 10, 2025
e8a1ccf
Fixed enum error.
Shugenya Sep 10, 2025
e10b526
Added component param to CLI.
Shugenya Sep 10, 2025
6dea204
Fixed function param
Shugenya Sep 10, 2025
3229502
Removed unused code.
Shugenya Sep 10, 2025
7fd437a
Replaced chrono with time.
Shugenya Sep 10, 2025
c4c1c9f
Use macro sqlx::query!.
Shugenya Sep 11, 2025
f53ef71
Moved DB connection outside the match block (so it can be used by oth…
Shugenya Sep 11, 2025
eabeb8a
Added conversion logic for DeploymentState.
Shugenya Sep 11, 2025
b4ee882
Added buffer time for deployments.
Shugenya Sep 11, 2025
f9c64a6
Changed CLI interface - new operation modes and params
Shugenya Sep 11, 2025
0d7dda9
Fixed comment.
Shugenya Sep 11, 2025
3a81c4f
Renamed Reserve Mode.
Shugenya Sep 11, 2025
77ac924
Updated region param name.
Shugenya Sep 11, 2025
4eac83d
Changed environment to enum.
Shugenya Sep 11, 2025
db2533a
Updated Finish and Cancel to use deployment_id
Shugenya Sep 11, 2025
68a3d1c
Merged environment fetching into 1 single query.
Shugenya Sep 12, 2025
28765f9
Replaced `query_as` with `query!` macro.
Shugenya Sep 12, 2025
6502f64
Composite index on (region, component) for better performance.
Shugenya Sep 12, 2025
da2261b
renamed struct PendingDeployment to Deployment.
Shugenya Sep 12, 2025
ec16bf5
Added all fields + buffer_time in Deployment strucy.
Shugenya Sep 12, 2025
bc8856b
Improved impl for DeploymentState to include also Finished and Cancel…
Shugenya Sep 12, 2025
af8b6ae
simplified error handling.
Shugenya Sep 12, 2025
7a5389b
Added logic to finish, cancel and start deployment.
Shugenya Sep 12, 2025
2d60b64
Update deploy-queue/src/main.rs
Shugenya Sep 15, 2025
9cf9cd7
Update deploy-queue/src/main.rs
Shugenya Sep 15, 2025
855c792
Update deploy-queue/src/main.rs
Shugenya Sep 15, 2025
65a4bc0
separate `update_deployment_record` into 3 separate methods.
Shugenya Sep 15, 2025
24bdd81
Update deploy-queue/src/main.rs
Shugenya Sep 15, 2025
a365bbe
Update deploy-queue/src/main.rs
Shugenya Sep 15, 2025
c442947
read database_url from env variable.
Shugenya Sep 15, 2025
e9580a2
Update deploy-queue/src/main.rs
Shugenya Sep 16, 2025
b844607
Update deploy-queue/src/main.rs
Shugenya Sep 16, 2025
d910544
Update deploy-queue/src/main.rs
Shugenya Sep 16, 2025
866cc94
Update deploy-queue/src/main.rs
Shugenya Sep 16, 2025
565462b
Removed unused variable.
Shugenya Sep 16, 2025
32cbe04
Moved state validation to DB level.
Shugenya Sep 16, 2025
6816f9b
Added info mode.
Shugenya Sep 16, 2025
c25e012
Update deploy-queue/src/main.rs
Shugenya Sep 16, 2025
a1e5ad0
Version is not mandatory field.
Shugenya Sep 16, 2025
d74eb98
Added immutable fields check on update.
Shugenya Sep 16, 2025
fe30c8e
Added validation that cancellation note can only be set when cancelling.
Shugenya Sep 16, 2025
94ca009
Make version param optional also in the CLI method.
Shugenya Sep 16, 2025
474437c
Removed reqwest and serde dependency.
Shugenya Sep 16, 2025
24c1508
Update deploy-queue/src/cli.rs
Shugenya Sep 16, 2025
fb5d77c
Added migrate macro dependency.
Shugenya Sep 16, 2025
d53d9ea
Added AsRef and ToString implementation for Environment.
Shugenya Sep 16, 2025
bf7a009
Added rerun if migrations change.
Shugenya Sep 16, 2025
d1b13da
Moved DB schema into migrations folder.
Shugenya Sep 16, 2025
743d4bb
Add Migrator and run_migrations function.
Shugenya Sep 16, 2025
f395690
Fixed Display method for Environment.
Shugenya Sep 16, 2025
2a31174
Fixed Deploy Queue GitHub action.
Shugenya Sep 16, 2025
908ab6d
Added migration run after connecting to DB.
Shugenya Sep 17, 2025
9065cbf
Removed validation on no state-related fields
Shugenya Sep 17, 2025
651bcf1
Update deploy-queue/src/main.rs
Shugenya Sep 17, 2025
a1367df
Fixed conflicting implementations of trait `ToString` for type `Envir…
Shugenya Sep 17, 2025
d0b3481
Fixed error with input parameters for insert_deployment_record.
Shugenya Sep 17, 2025
d20d4d6
Fixed build errors with time libraries.
Shugenya Sep 17, 2025
c618145
Fixed build error with reference.
Shugenya Sep 17, 2025
bba89e1
Fixed build error with Option<NonZero<u64>>.
Shugenya Sep 17, 2025
1cc0d66
Removed unused reference.
Shugenya Sep 17, 2025
d7de52f
Fixed deployment variable reference error.
Shugenya Sep 17, 2025
5fd99e1
Fixed type mismatch in db connection error handling.
Shugenya Sep 17, 2025
b474a56
Fixed error type mismatch
Shugenya Sep 17, 2025
f2fe421
Type inference error fixed.
Shugenya Sep 17, 2025
572a341
Fixed i32 to i64 conversion.
Shugenya Sep 17, 2025
075ead8
Clone borrowed values to fix build error.
Shugenya Sep 17, 2025
5fc0d2e
Added missing Ok statement.
Shugenya Sep 17, 2025
f69f2f1
Fixed ownership error.
Shugenya Sep 17, 2025
df69bdb
added DEPLOY_QUEUE_DATABASE_URL variable to yml.
Shugenya Sep 17, 2025
f01ad60
Added DB schema setup step.
Shugenya Sep 17, 2025
9ed8acf
Fixed missing table error on build.
Shugenya Sep 17, 2025
1688622
Missing version field in query.
Shugenya Sep 17, 2025
7143bf9
Setup database schema step also for build-image job.
Shugenya Sep 17, 2025
bad81e9
missing version field in DB query.
Shugenya Sep 17, 2025
60ec676
Added query cache for build-image job.
Shugenya Sep 17, 2025
8475f37
Added dependency check.
Shugenya Sep 17, 2025
288de19
Fixed dependency - sqlx
Shugenya Sep 17, 2025
cf2d885
Replaced MutexBot reference in creating release.
Shugenya Sep 17, 2025
50a4880
Info was printing wrong ID.
Shugenya Sep 18, 2025
1fea9e9
Update deploy-queue/src/main.rs
Shugenya Sep 18, 2025
8b53447
Added back download binary step.
Shugenya Sep 18, 2025
b008e95
Added concurrency key parameter.
Shugenya Sep 18, 2025
fd29d56
owned data + move instead of borrowed data + clone for Deployment struct
jcgruenhage Sep 18, 2025
1ac5f53
Renamed first migration for consistency with sqlx migrate add.
Shugenya Sep 18, 2025
aa9630a
Added constraint for environment allowed values on DB level.
Shugenya Sep 18, 2025
c43e72e
Added `concurrency_key` input to yml.
Shugenya Sep 18, 2025
4a774e1
Fixed mutexbot reference.
Shugenya Sep 18, 2025
d6fe4ab
Fixed failed test (environment constraint)
Shugenya Sep 18, 2025
e604b07
Fixed error when triggering start deployment action.
Shugenya Sep 18, 2025
e39ecf2
Removed not needed env variable.
Shugenya Sep 18, 2025
ffdef95
Reset version to 0.1.0
Shugenya Sep 18, 2025
c8d32c4
Added DB service in the test-deploy-queue-action.
Shugenya Sep 19, 2025
895a24b
Update deploy-queue/src/cli.rs
Shugenya Sep 19, 2025
9ebf2b6
Added job for pre-release cleanup.
Shugenya Sep 19, 2025
80508fe
Fixed error with cli arguments.
Shugenya Sep 19, 2025
9873003
Fixed optional input parameters in Deploy Queue action.
Shugenya Sep 19, 2025
1165b4f
Fixed error with cancellation note parameter.
Shugenya Sep 19, 2025
268e1d7
Separate lint job with DB migration check.
Shugenya Sep 22, 2025
baab6d7
Extracted logic for printing summary.
Shugenya Sep 22, 2025
396a19e
Fixed imports.
Shugenya Sep 22, 2025
9069578
Add SQLx query cache for offline compilation
Shugenya Sep 22, 2025
7e3a08d
Move migration macro inline.
Shugenya Sep 22, 2025
bbc3ab2
Fixed lint errors
Shugenya Sep 22, 2025
aa21f2a
Updated lock file
Shugenya Sep 22, 2025
7661a6a
Removed `cargo clippy --locked`
Shugenya Sep 22, 2025
c802064
Added `cargo clippy --locked` back.
Shugenya Sep 22, 2025
39a05a9
rework summary
jcgruenhage Sep 22, 2025
ade9e8f
reformat
jcgruenhage Sep 22, 2025
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
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Mutexbot PR pre-release cleanup
name: Deploy Queue PR pre-release cleanup

on:
pull_request:
types: ["closed"]
branches: ["main"]
paths: ["mutexbot/**"]
paths: ["deploy-queue/**"]

permissions: {}

Expand All @@ -24,7 +24,7 @@ jobs:
- name: Delete pre-release for closed PR
run: |
echo "Deleting pre-release for PR #${{ github.event.pull_request.number }}"
gh release delete "mutexbot-pr-${{ github.event.pull_request.number }}" \
gh release delete "deploy-queue-pr-${{ github.event.pull_request.number }}" \
--yes \
--cleanup-tag
env:
Expand Down
199 changes: 141 additions & 58 deletions .github/workflows/mutexbot.yml → .github/workflows/deploy-queue.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name: Mutexbot
name: Deploy Queue

on:
pull_request:
types: ["opened", "synchronize", "reopened"]
branches: ["main"]
paths: ["mutexbot/**"]
paths: ["deploy-queue/**"]
push:
branches: ["main"]
paths: ["mutexbot/**"]
tags: ["mutexbot-v*.*.*"]
paths: ["deploy-queue/**"]
tags: ["deploy-queue-v*.*.*"]

permissions:
contents: read
Expand All @@ -17,6 +17,72 @@ env:
GHCR_REPO: ghcr.io/neondatabase/dev-actions

jobs:
lint:
runs-on: ubuntu-24.04
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: deploy_queue_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/deploy_queue_test
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
with:
egress-policy: audit

- name: Fetch deploy-queue folder
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
sparse-checkout: deploy-queue

- name: Verify migrations work
working-directory: deploy-queue
run: |
# PostgreSQL is already healthy thanks to health checks
# Install sqlx-cli to run migrations
cargo install sqlx-cli --no-default-features --features postgres

# Apply migrations to verify they work correctly
sqlx migrate run

echo "Database migrations completed successfully"

- name: Verify SQLx query cache is up-to-date
working-directory: deploy-queue
run: |
# Check that the query cache matches current queries
cargo sqlx prepare --check

echo "SQLx query cache is up-to-date"

- name: Check code formatting
working-directory: deploy-queue
run: |
# Verify code is properly formatted
cargo fmt --all -- --check

echo "Code formatting check passed"

- name: Lint and verify lockfile
working-directory: deploy-queue
run: |
# Run clippy with locked dependencies to ensure lockfile is up-to-date
cargo clippy --locked --all-targets --all-features -- -D warnings

echo "Linting and lockfile verification completed"

build-image:
runs-on: ${{ matrix.runner }}
outputs:
Expand All @@ -37,10 +103,10 @@ jobs:
with:
egress-policy: audit

- name: Fetch mutexbot folder
- name: Fetch deploy-queue folder
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
sparse-checkout: mutexbot
sparse-checkout: deploy-queue

- name: Docker meta
id: meta
Expand All @@ -62,7 +128,7 @@ jobs:
id: build
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6.15.0
with:
context: mutexbot
context: deploy-queue
labels: ${{ steps.meta.outputs.labels }}
attests: |
type=provenance,mode=max
Expand Down Expand Up @@ -106,11 +172,11 @@ jobs:
images: ${{ env.GHCR_REPO }}
tags: |
# branch event
type=ref,enable=true,priority=600,prefix=mutexbot-,suffix=,event=branch
type=ref,enable=true,priority=600,prefix=deploy-queue-,suffix=,event=branch
# pull request event
type=ref,enable=true,priority=600,prefix=mutexbot-pr-,suffix=,event=pr
type=ref,enable=true,priority=600,prefix=deploy-queue-pr-,suffix=,event=pr
# tags event
type=match,pattern=mutexbot-v(.*)
type=match,pattern=deploy-queue-v(.*)

- name: Create manifest list and push
run: |
Expand All @@ -135,29 +201,29 @@ jobs:
with:
egress-policy: audit

- name: Fetch mutexbot folder
- name: Fetch deploy-queue folder
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
sparse-checkout: mutexbot
sparse-checkout: deploy-queue

- name: Build binary
working-directory: mutexbot
working-directory: deploy-queue
run: |
TARGET="$(uname -m)-unknown-linux-musl"
echo "TARGET=${TARGET}" | tee -a "${GITHUB_ENV}"
rustup target add "${TARGET}"
sudo apt-get update && sudo apt-get install -y musl-tools musl-dev
cargo install cargo-auditable --locked
cargo auditable build --release --target "${TARGET}"
cp "target/${TARGET}/release/mutexbot" assets/
mv assets "mutexbot-${TARGET}"
cp "target/${TARGET}/release/deploy-queue" assets/
mv assets "deploy-queue-${TARGET}"

- name: Upload artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: mutexbot-${{ env.TARGET }}
path: mutexbot/mutexbot-${{ env.TARGET }}
name: deploy-queue-${{ env.TARGET }}
path: deploy-queue/deploy-queue-${{ env.TARGET }}

create-release:
needs: [build-binary]
Expand All @@ -178,7 +244,7 @@ jobs:
- name: Create archives
run: |
for artifact in $(ls); do
chmod a+x "${artifact}/mutexbot"
chmod a+x "${artifact}/deploy-queue"
tar cvf "${artifact}.tar.zst" "${artifact}"
done

Expand All @@ -190,14 +256,14 @@ jobs:
--title "Release ${{ github.ref_name }}" \
--notes "Release for ${{ github.ref_name }}" \
--verify-tag \
mutexbot-*.tar.zst
deploy-queue-*.tar.zst
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Create or update pre-release
if: github.event_name == 'pull_request'
run: |
TAG="mutexbot-pr-${{ github.event.pull_request.number }}"
TAG="deploy-queue-pr-${{ github.event.pull_request.number }}"

# Delete existing pre-release if it exists
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
Expand All @@ -214,67 +280,84 @@ jobs:
--prerelease \
--title "Pre-release for $TAG" \
--notes "Pre-release for $TAG" \
mutexbot-*.tar.zst
deploy-queue-*.tar.zst
env:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

test-mutexbot-action:
test-deploy-queue-action:
if: github.event_name == 'pull_request' || github.ref_type == 'tag'
needs: [create-release]
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: deploy_queue_test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
env:
DEPLOY_QUEUE_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/deploy_queue_test
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
with:
egress-policy: audit

- name: Fetch mutexbot folder
- name: Fetch deploy-queue folder
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
sparse-checkout: mutexbot
sparse-checkout: deploy-queue

- name: Reserve test-resource as component A
uses: ./mutexbot
- name: Start deployment for test-resource as component A
uses: ./deploy-queue
with:
api_key: ${{ secrets.MUTEXBOT_API_KEY_TEST_COMPONENT_A }}
mode: reserve
resource_name: test-resource
isolation_channel: ${{ vars.MUTEXBOT_CHANNEL_TESTING }}

- name: Try (and fail) to reserve test-resource as component B
uses: ./mutexbot
mode: start
region: test-region
component: test-component
environment: dev
version: test-version
url: test-url
note: test-note

- name: Try (and fail) to start deployment for test-resource as component B
uses: ./deploy-queue
continue-on-error: true
timeout-minutes: 1
with:
api_key: ${{ secrets.MUTEXBOT_API_KEY_TEST_COMPONENT_B }}
mode: reserve
resource_name: test-resource
isolation_channel: ${{ vars.MUTEXBOT_CHANNEL_TESTING }}

- name: Try (and fail) to release as component B
uses: ./mutexbot
mode: start
region: test-region
component: test-component
environment: dev
version: test-version
url: test-url
note: test-note

- name: Try (and fail) to finish deployment for component B
uses: ./deploy-queue
continue-on-error: true
timeout-minutes: 1
with:
api_key: ${{ secrets.MUTEXBOT_API_KEY_TEST_COMPONENT_B }}
mode: release
resource_name: test-resource
isolation_channel: ${{ vars.MUTEXBOT_CHANNEL_TESTING }}
mode: finish
deployment_id: 1234567890


- name: Reduce reservation as component A
uses: ./mutexbot
- name: Cancel deployment as component B
uses: ./deploy-queue
with:
api_key: ${{ secrets.MUTEXBOT_API_KEY_TEST_COMPONENT_A }}
mode: reserve
duration: 10m
resource_name: test-resource
isolation_channel: ${{ vars.MUTEXBOT_CHANNEL_TESTING }}

- name: Force release as component B
uses: ./mutexbot
mode: cancel
deployment_id: 1234567890
cancellation_note: test-cancellation-note

- name: Get info about deployment
uses: ./deploy-queue
with:
api_key: ${{ secrets.MUTEXBOT_API_KEY_TEST_COMPONENT_B }}
mode: force-release
resource_name: test-resource
isolation_channel: ${{ vars.MUTEXBOT_CHANNEL_TESTING }}
mode: info
deployment_id: 1234567890
File renamed without changes.

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

Loading
Loading