mirror of
https://github.com/dsec-hub/dsec-discord-bot.git
synced 2026-09-22 15:53:56 +00:00
SEC-01: add pull-request CI and stop the deploy leaving DOT_ENV on the VPS
A merge to main runs the merged commit as root on the club VPS through the self-hosted runner, and this repo has no PR CI, no required review and no status check. - .github/workflows/ci.yml: fmt / clippy / build --locked / test on ubuntu-latest, contents: read, both actions pinned by commit SHA. Never the VPS. - deploy.yml: keep push to main, add workflow_dispatch, permissions contents: read, environment: production, and an if: always() step that removes the .env the deploy writes into the workspace. - .dockerignore: keep that .env, target/ and .git out of the build context. - Dockerfile: --locked on both cargo build --release lines. environment: production gates nothing until required reviewers are configured on the environment itself, and the ruleset still requires zero approving reviews. Both are owner-only and listed in the pull request. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
88e50b1dc4
commit
9932bdcecb
4 changed files with 107 additions and 2 deletions
9
.dockerignore
Normal file
9
.dockerignore
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# Keep the docker build context to what the Dockerfile actually COPYs
|
||||
# (Cargo.toml, Cargo.lock, src). deploy.yml writes the DOT_ENV secret to .env in
|
||||
# the workspace before running `docker compose up --build`; without this file
|
||||
# that secret is tarred into the build context and handed to the docker daemon
|
||||
# on every deploy.
|
||||
.env
|
||||
.env.*
|
||||
target/
|
||||
.git
|
||||
82
.github/workflows/ci.yml
vendored
Normal file
82
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Format, lint, build and test on every pull request.
|
||||
#
|
||||
# This must run on a GitHub-hosted runner and never on the club VPS. The runner
|
||||
# deploy.yml uses lives on the club's own server and executes whatever a workflow
|
||||
# tells it to, as root, so nothing triggered by a pull request may be pointed at
|
||||
# it. Read that as a rule for this file, not a property of the repository: this
|
||||
# repo is public, forking is on, and fork pull requests only need approval from a
|
||||
# first-time contributor, so a fork that brings its own workflow can still reach
|
||||
# that runner. See SEC-01.
|
||||
#
|
||||
# SEC-01: point the protect-main ruleset's required status check at this job's
|
||||
# name ("fmt / clippy / build / test") so a red build blocks the merge that
|
||||
# deploys.
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
# A newer push to the same pull request makes an in-flight run irrelevant.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: fmt / clippy / build / test
|
||||
runs-on: ubuntu-latest
|
||||
# A cold build of this dependency tree (serenity, reqwest, image, exr) in
|
||||
# release, then clippy, then test, is slow on a 4-vCPU hosted runner. This is
|
||||
# a guard against a hung job, not a target.
|
||||
timeout-minutes: 45
|
||||
|
||||
steps:
|
||||
# Third-party and first-party actions alike are pinned to a full commit
|
||||
# SHA: a tag is mutable and can be repointed at new code by whoever owns
|
||||
# the action.
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
# Caches written by a pull_request run are scoped to that pull request, so
|
||||
# this pays off across pushes to the same branch rather than across branches.
|
||||
- name: Cache cargo registry and build artifacts
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
|
||||
# actions/runner-images documents rustfmt for ubuntu-24.04 but not clippy (it
|
||||
# lists clippy only under ubuntu-22.04), while the image actually in use does
|
||||
# ship it. Adding both components is a no-op when they are present and keeps
|
||||
# this job working if that undocumented extra ever goes away. Print the
|
||||
# versions too: clippy's lint set moves between releases, so knowing which one
|
||||
# ran is what explains a lint that appeared from nowhere.
|
||||
- name: Toolchain
|
||||
run: |
|
||||
rustup component add clippy rustfmt
|
||||
cargo --version
|
||||
cargo fmt --version
|
||||
cargo clippy --version
|
||||
|
||||
- name: Format
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
# Kept ahead of clippy and test: those resolve dependencies and would
|
||||
# refresh Cargo.lock in place, so a stale lockfile would slip past
|
||||
# --locked if they ran first.
|
||||
- name: Build
|
||||
run: cargo build --locked --release
|
||||
|
||||
- name: Clippy
|
||||
run: cargo clippy --all-targets -- -D warnings
|
||||
|
||||
- name: Test
|
||||
run: cargo test
|
||||
14
.github/workflows/deploy.yml
vendored
14
.github/workflows/deploy.yml
vendored
|
|
@ -4,10 +4,19 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- main
|
||||
# Manual re-run, for redeploying after a rollback or re-creating the
|
||||
# workspace .env that the cleanup step below now removes.
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build_and_deploy:
|
||||
runs-on: [self-hosted, linux]
|
||||
# SEC-01: this gates nothing until required reviewers are configured on the
|
||||
# "production" environment itself. See the pull request description.
|
||||
environment: production
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
|
@ -35,5 +44,10 @@ jobs:
|
|||
sudo docker compose up -d --build --force-recreate
|
||||
echo "Deployment complete."
|
||||
|
||||
- name: Remove environment file
|
||||
if: always()
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: rm -f .env
|
||||
|
||||
- name: Clean up old Docker images
|
||||
run: sudo docker image prune -f
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ RUN mkdir src && \
|
|||
echo 'fn main() { println!("Dummy main for dependency caching"); }' > src/main.rs
|
||||
|
||||
# Build dependencies (this layer will be cached unless Cargo.toml/Cargo.lock changes)
|
||||
RUN cargo build --release && \
|
||||
RUN cargo build --locked --release && \
|
||||
rm -rf src target/release/deps/dsec_bot*
|
||||
|
||||
# Copy the actual source code
|
||||
COPY src ./src
|
||||
|
||||
# Build the actual application
|
||||
RUN cargo build --release
|
||||
RUN cargo build --locked --release
|
||||
|
||||
# Runtime stage - use a minimal image
|
||||
FROM debian:bookworm-slim
|
||||
|
|
|
|||
Loading…
Reference in a new issue