Skip to content

fix(ci): Let destroy-all run on a stack that has no D1 database - #945

Merged
stefanko-ch merged 1 commit into
mainfrom
fix/destroy-without-d1
Oct 29, 2026
Merged

stefanko-ch merged 1 commit into
mainfrom
fix/destroy-without-d1

Conversation

@stefanko-ch

@stefanko-ch stefanko-ch commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

destroy-all.yml read the enabled services from D1 before anything else, and stopped when the query failed. A stack that was set up but never deployed has no D1 database, so its destroy could never succeed.

Nexus-Conductor will not delete a user's repository until a destroy succeeds. A never-deployed Conductor user (yara-koch, run 1 on that user's fork) therefore failed at "Generate config.tfvars" and could not be removed.

The fix: when the query fails, the step now asks whether the database exists.

  • Absent only if wrangler d1 list --json succeeds and its list does not contain the name. A failed or unparsable listing is still a failure.
  • With the database absent, the destroy goes on with no enabled services:
    • tofu destroy acts on the state;
    • the existing init step already skips the destroy when the state bucket is missing too, which is the never-deployed case.

Checks

  • The absent-check was run against the real account's D1 list:
    • nexus-yara-koch-nona-company-db reads as absent;
    • nexus-deads8-test-nona-company-db reads as present;
    • garbage input fails jq -e (rc 5) and takes the error path.
  • Workflow tests: 105 passed. actionlint is clean.

Local review

CodeRabbit CLI on 1b5d91c5: 0 findings.

Not yet verified

The fix has not run on a real fork; it needs a release first.

How to test

After the release reaches the Conductor template mirror, run destroy for yara-koch (class BIA22) in Conductor. Expect:

  1. "D1 database … does not exist" in the log.
  2. "R2 credentials not found" or "R2 state bucket not found", then the destroy is skipped.
  3. A green run.

Summary by Sourcery

Bug Fixes:

  • Allow destroy workflows to proceed for stacks whose D1 database is absent, while still failing safely when the database lookup or account-wide database listing cannot be verified.

destroy-all read the enabled services from D1 before anything else and
failed when the query did. A stack that was set up but never deployed
has no D1 database, so its destroy could never succeed — and
Nexus-Conductor will not delete a user's repository until one does.
Seen on a Conductor user whose stack was never deployed.

When the query fails, the step now asks whether the database exists.
Only a successful listing that does not contain it counts as absent;
a failed or unparsable listing is still a failure. With the database
absent, the destroy proceeds with no enabled services: tofu destroy
acts on the state, and the init step already skips the destroy when
the state bucket is missing too.
@sourcery-ai

sourcery-ai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Sorry @stefanko-ch, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 5 days and 4 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@coderabbitai

coderabbitai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 0ed5732 and 1b5d91c.

Files selected for processing: 1
  • .github/workflows/destroy-all.yml
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Reviewer's Guide

The workflow now distinguishes a genuinely absent D1 database from an unavailable or invalid D1 lookup, allowing never-deployed stacks to reach the existing state checks and complete destroy successfully without weakening error handling.

Flow diagram for handling an absent D1 database during destroy

flowchart TD
    A[Read enabled services from D1] --> B{D1 query failed?}
    B -->|No| C[Continue with enabled services]
    B -->|Yes| D[Run wrangler d1 list --json]
    D --> E{Database absent and listing valid?}
    E -->|Yes| F[Set empty enabled services]
    E -->|No| G[Fail destroy]
    F --> H[Run existing state checks]
    C --> H
    H --> I[OpenTofu destroy or skip when state bucket is missing]
Loading

File-Level Changes

Change Details Files
Allow destroy workflows to proceed when the stack’s D1 database is confirmed absent.
  • When the enabled-services query fails, list account D1 databases with Wrangler.
  • Treat the database as absent only when the listing succeeds, parses successfully, and excludes the target name.
  • Use an empty enabled-services result for absent databases; retain the existing failure path for listing or parsing errors.
  • Preserve downstream state-bucket checks so never-deployed stacks are skipped safely.
.github/workflows/destroy-all.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions

Copy link
Copy Markdown
Contributor

coverage

Coverage report — nexus_deploy
FileStmtsMissCoverMissing
__init__.py50100% 
_remote.py420100% 
cli.py40100% 
compose_restart.py400100% 
compose_runner.py1020100% 
config.py1920100% 
firewall.py2060100% 
forgejo.py5985590%783–784, 789, 812–813, 825–826, 862–863, 875–876, 894–895, 920–921, 943–944, 955–956, 1011–1012, 1020–1021, 1026, 1032–1033, 1057–1058, 1091–1092, 1095, 1126–1127, 1168–1169, 1174–1175, 1215–1216, 1247–1248, 1271–1272, 1277–1278, 1377–1378, 1383–1384, 1860, 1864, 1885, 1913–1914, 2001
forgejo_runner.py47197%228
hetzner_capacity.py1680100% 
hetzner_snapshot.py2020100% 
infisical.py2300100% 
kestra.py177398%227, 441, 802
orchestrator.py6867788%205, 504–505, 517, 618, 810, 822, 992–993, 998–999, 1031–1033, 1042, 1047–1049, 1060, 1097–1098, 1103–1104, 1124, 1159–1160, 1165–1166, 1174, 1199–1200, 1208, 1279–1280, 1285–1286, 1338–1339, 1344–1345, 1596, 1599, 1669, 1675–1676, 1681–1682, 1716, 1840–1841, 1846–1847, 1896–1897, 1902–1903, 1962, 1977, 2034, 2039–2040, 2045–2046, 2053, 2059, 2234, 2241, 2253–2254, 2259–2260, 2266, 2272, 2356–2357, 2378–2379
pg_preflight.py191199%214
pipeline.py2521394%166–167, 351, 429, 528, 569, 664–665, 710–711, 801–802, 849
r2_tokens.py113298%87, 150
s3_persistence.py299199%315
s3_restore.py1350100% 
secret_sync.py990100% 
seeder.py980100% 
service_env.py6253394%2504, 2506–2508, 2516–2517, 3111–3114, 3119–3125, 3192–3196, 3212–3216, 3240, 3242, 3264–3265, 3272, 3399
services.py372199%3132
setup.py1651392%245, 315–318, 326, 330–335, 351
ssh.py520100% 
stack_sync.py960100% 
tfvars.py440100% 
tofu.py860100% 
workspace_coords.py1010100% 
TOTAL542720096% 

@codecov

codecov Bot commented Oct 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@stefanko-ch
stefanko-ch merged commit d6485a0 into main Oct 29, 2026
15 checks passed
@stefanko-ch
stefanko-ch deleted the fix/destroy-without-d1 branch October 29, 2026 14:59
stefanko-ch pushed a commit that referenced this pull request Oct 29, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.87.0](v0.86.0...v0.87.0)
(2026-10-29)


### 🚀 Features

* **control-plane:** Drive the lifecycle buttons on a Forgejo-hosted
fork ([#946](#946))
([b04a57e](b04a57e))


### 🐛 Bug Fixes

* **ci:** Let destroy-all run on a stack that has no D1 database
([#945](#945))
([d6485a0](d6485a0))
* **stacks:** Let the Forgejo runner take four jobs on three CPUs
([#944](#944))
([4cc3fc3](4cc3fc3))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

## Summary by Sourcery

Release version 0.87.0 with Forgejo lifecycle controls and fixes for
stack cleanup and runner capacity.

New Features:
- Add lifecycle button control for forks hosted on Forgejo.

Bug Fixes:
- Allow destroy-all to run for stacks without a D1 database.
- Increase Forgejo runner capacity to four jobs on three CPUs.

Documentation:
- Document the 0.87.0 release in the changelog.

Chores:
- Bump the release manifest to version 0.87.0.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant