From fde5a4edde29ad7159227028d7ef619051d8cbbc Mon Sep 17 00:00:00 2001 From: edwh Date: Wed, 1 Jul 2026 13:01:52 +0100 Subject: [PATCH 1/2] ci: stop restarters-dev nightly to save cost Adds a scheduled GitHub Actions workflow that stops the restarters-dev Fly machine(s) every night at 02:00 UTC. auto_stop_machines is "off" so Fly won't undo the stop, and auto_start_machines is true so the box boots again on the next request in the morning. Reuses the existing FLY_API_TOKEN repo secret. Off overnight (no CPU billing), back on demand; the volume persists so no data is lost. Also runnable manually via workflow_dispatch. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/stop-dev-nightly.yml | 45 ++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/stop-dev-nightly.yml diff --git a/.github/workflows/stop-dev-nightly.yml b/.github/workflows/stop-dev-nightly.yml new file mode 100644 index 000000000..d8dceb702 --- /dev/null +++ b/.github/workflows/stop-dev-nightly.yml @@ -0,0 +1,45 @@ +name: Stop restarters-dev nightly + +# Stops the restarters-dev Fly machine(s) every night to avoid paying for the +# dev/staging box while it sits idle overnight. +# +# How it stays cheap but stays usable: +# * fly.dev.toml has auto_stop_machines = "off", so Fly never auto-stops the +# box during the day AND never auto-restarts a machine we stop here +# (min_machines_running is only enforced when auto_stop is enabled, so it is +# inert for us — verified: a manual `fly machine stop` stays stopped). +# * fly.dev.toml has auto_start_machines = true, so the machine boots again +# automatically the first time anyone makes a request in the morning. +# +# Net effect: off overnight (no CPU billing), back on demand. A stopped machine +# still keeps its volume, so no data is lost. +# +# NOTE ON TIME: GitHub Actions cron is UTC and does NOT follow BST/DST. +# 0 2 * * * == 02:00 UTC == 03:00 London in summer (BST) / 02:00 in winter. +# Adjust the cron if you want exactly 02:00 London year-round. + +on: + schedule: + - cron: '0 2 * * *' # 02:00 UTC daily + workflow_dispatch: {} # allow manual runs from the Actions tab + +jobs: + stop-dev: + runs-on: ubuntu-latest + steps: + - uses: superfly/flyctl-actions/setup-flyctl@master + - name: Stop all restarters-dev machines + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} + run: | + set -euo pipefail + ids=$(flyctl machine list -a restarters-dev --json | jq -r '.[].id') + if [ -z "$ids" ]; then + echo "No machines found for restarters-dev — nothing to stop." + exit 0 + fi + for id in $ids; do + echo "Stopping machine $id" + flyctl machine stop "$id" -a restarters-dev + done + echo "Done. Machines will auto-start on the next request." From 83ec6b29e0c5a8ef7f6d41962b9d93ce75cd5ca5 Mon Sep 17 00:00:00 2001 From: edwh Date: Fri, 3 Jul 2026 16:13:53 +0100 Subject: [PATCH 2/2] ci: pin setup-flyctl action to a commit SHA (SonarCloud S7637) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pin superfly/flyctl-actions/setup-flyctl from @master to the full commit SHA ed8efb3 (master as of 2026-07-03). Satisfies SonarCloud's new_security_rating gate (rule githubactions:S7637 — pin actions to a full-length commit SHA to prevent a moving tag/branch from silently introducing malicious code). --- .github/workflows/stop-dev-nightly.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stop-dev-nightly.yml b/.github/workflows/stop-dev-nightly.yml index d8dceb702..e7e3d0d68 100644 --- a/.github/workflows/stop-dev-nightly.yml +++ b/.github/workflows/stop-dev-nightly.yml @@ -27,7 +27,9 @@ jobs: stop-dev: runs-on: ubuntu-latest steps: - - uses: superfly/flyctl-actions/setup-flyctl@master + # Pinned to a full commit SHA (supply-chain hardening; SonarCloud S7637). + # ed8efb3 = superfly/flyctl-actions master as of 2026-07-03. + - uses: superfly/flyctl-actions/setup-flyctl@ed8efb33836e8b2096c7fd3ba1c8afe303ebbff1 - name: Stop all restarters-dev machines env: FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}