Skip to content

fix(deploy): don't wrap down/ps/logs compose calls in op run - #73

Merged
owine merged 2 commits into
mainfrom
fix/teardown-op-run-coupling
Jul 9, 2026
Merged

fix(deploy): don't wrap down/ps/logs compose calls in op run#73
owine merged 2 commits into
mainfrom
fix/teardown-op-run-coupling

Conversation

@owine

@owine owine commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Problem

The Teardown removed stacks step runs before the git reset --hard (it needs the pre-reset compose files to tear down stacks the commit deleted). So it reads the previous compose.env.

When a commit both removes a stack and drops a now-orphaned var whose 1Password item was already archived, op run resolves the entire env-file up front, hits the dead ref, and aborts before docker compose down runs. Result:

  • The removed stack's containers are never stopped.
  • The failure is only a ::warning::down failed for <stack>, so the deploy job stays green.
  • CI can't self-heal on a re-run — prepare no longer detects the stack as removed (previous_sha == target), so the teardown step won't fire again. Cleanup then requires a manual docker compose -p <stack> down on the host.

This actually happened on docker-zendc: media/logging/librarymanager were left running ~38h after their "successful" removal deploy, because the pre-reset compose.env still referenced the long-archived zendc-zencommand item.

Fix

docker compose down / ps / logs operate on already-created resources by compose project label and need no resolved secrets. Only up genuinely requires op run (it injects env into new containers).

This strips op run --env-file from all 17 inline down/ps/logs calls, leaving the 4 up calls wrapped. A ${VAR} in a torn-down file simply resolves to empty (no ${VAR:?} guards exist in any caller compose file; all networks are external: true, which down never removes), so teardown and failure-diagnostics no longer depend on compose.env being fully resolvable.

Why this is safe / not a regression

Git history shows no secrets-driven rationale in any commit that introduced these wrapped calls:

  • Diagnostics ps/logs (8a812a3) — a diagnostics feature; op run applied uniformly alongside the up in the same helper.
  • Teardown/cleanup down (301c863, 406ed43, self-hosted rewrite) — messages are about clearing orphans, never secrets.
  • The adjacent docker inspect calls were already unwrapped — the author already knew label/name-based inspection needs no op run.

Verification

  • yamllint --strict
  • actionlint (includes shellcheck on run: blocks) ✅
  • Only the 4 multiline timeout … op run … -- \ + docker compose up calls retain op run; 0 inline wrapped calls remain.

Non-breaking (no input changes) — callers pick it up via Renovate's SHA-pin bump.

Summary by Sourcery

Simplify deploy workflow Docker Compose interactions to avoid teardown failures caused by unresolved 1Password env references.

Enhancements:

  • Remove 1Password op run wrapping from all Docker Compose down/ps/logs calls in the deploy workflow while keeping up calls wrapped for secret injection.
  • Document in the deploy workflow why teardown and diagnostics steps run Compose commands directly without op run to ensure reliable stack cleanup.

CI:

  • Adjust deploy GitHub Actions workflow so stack teardown and diagnostics no longer depend on resolving the compose.env via 1Password.

The "Teardown removed stacks" step runs before the git reset, so it reads
the previous compose.env. When a commit removes a stack and also drops a
now-orphaned var whose 1Password item was already archived, `op run`
fails to resolve that dead ref and aborts — before `docker compose down`
executes. The removed stack's containers are never stopped (the failure
is only a ::warning::, so the job stays green), and CI can't self-heal on
a later run because the stack is no longer detected as removed.

`docker compose down`/`ps`/`logs` operate on already-created resources by
compose project label and need no resolved secrets — only `up` genuinely
requires op run to inject env into new containers. Every non-`up` call had
inherited the op run wrapper by copy-paste consistency (git history shows
no secrets-driven rationale in any of the introducing commits; the
adjacent `docker inspect` calls were already unwrapped).

Strip `op run --env-file` from all 17 inline down/ps/logs calls, leaving
the 4 `up` calls wrapped. Decouples teardown and failure diagnostics from
compose.env resolvability so a dead ref can't strand containers or hide
diagnostics.
@sourcery-ai

sourcery-ai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Reviewer's Guide

Removes 1Password op run wrapping from all inline docker compose down/ps/logs calls in the deploy workflow, while keeping it for up, to ensure teardown and diagnostics work even when compose.env contains archived secret references and to avoid silently leaving stacks running after removal or failed deploys.

Sequence diagram for deploy teardown and diagnostics without op run wrapping

sequenceDiagram
  actor Developer
  participant GitHubActions as GitHub_Actions_deploy_workflow
  participant ComposeEnv as compose_env
  participant OnePassword as op
  participant DockerCompose as docker_compose

  Developer->>GitHubActions: push commit removing stack and vars
  GitHubActions->>ComposeEnv: read_previous_compose_env

  alt removed_stack_teardown
    GitHubActions->>DockerCompose: docker compose down
    DockerCompose-->>GitHubActions: containers_stopped_by_project_label
  end

  alt diagnostics_ps_logs
    GitHubActions->>DockerCompose: docker compose ps -a
    DockerCompose-->>GitHubActions: container_status_json
    GitHubActions->>DockerCompose: docker compose logs --tail
    DockerCompose-->>GitHubActions: container_logs
  end

  opt deploy_new_stack_up
    GitHubActions->>OnePassword: op run --env-file compose.env
    OnePassword->>DockerCompose: docker compose up
    DockerCompose-->>GitHubActions: new_containers_started_with_secrets
  end
Loading

File-Level Changes

Change Details Files
Stop wrapping docker compose teardown commands in 1Password op run so they no longer depend on fully-resolvable compose.env and always execute.
  • Update the Teardown removed stacks step to call docker compose -f "$compose_file" down directly instead of via op run and document the rationale in comments.
  • Change all teardown/cleanup steps that previously used op run --env-file="$LIVE_REPO_PATH/compose.env" -- docker compose down to call docker compose down directly.
  • Adjust rollback logic to use plain docker compose -f "$compose_file" down for tearing down new stacks before rollback.
.github/workflows/deploy.yml
Stop wrapping diagnostics ps/logs commands in op run so failure analysis is independent of secrets resolution.
  • Change diagnostics helpers to invoke docker compose ps -a directly for listing and JSON output instead of via op run.
  • Update log tailing commands to use docker compose logs directly for both all-services and per-service tails.
  • Ensure critical stack health gating uses plain docker compose ps -a --format json instead of via op run, leaving docker inspect unchanged.
.github/workflows/deploy.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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The long explanatory comment about why down/ps/logs are not wrapped in op run is helpful but quite dense; consider tightening it or extracting the rationale into a short, referenced note to keep the workflow readable.
  • The diagnostics helper (docker compose ps + logs + docker inspect) is duplicated in multiple steps; consider factoring it into a reusable shell function or separate action to reduce repetition and keep future changes consistent.
  • Now that op run is removed from docker compose ps calls, ensure that any reliance on env-derived COMPOSE_PROJECT_NAME or other compose env settings is explicitly set elsewhere, or document that the default project naming is sufficient for these commands.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The long explanatory comment about why `down`/`ps`/`logs` are not wrapped in `op run` is helpful but quite dense; consider tightening it or extracting the rationale into a short, referenced note to keep the workflow readable.
- The diagnostics helper (`docker compose ps` + `logs` + `docker inspect`) is duplicated in multiple steps; consider factoring it into a reusable shell function or separate action to reduce repetition and keep future changes consistent.
- Now that `op run` is removed from `docker compose ps` calls, ensure that any reliance on env-derived `COMPOSE_PROJECT_NAME` or other compose env settings is explicitly set elsewhere, or document that the default project naming is sufficient for these commands.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Address Sourcery review: condense the rationale comment and document that
default compose project naming (stack dir basename) is what down/ps/logs
rely on — callers set no COMPOSE_* vars, so dropping op run doesn't change
which project these commands target.
@owine

owine commented Jul 9, 2026

Copy link
Copy Markdown
Owner Author

Thanks @sourcery-ai — addressed:

  • Project-naming / COMPOSE_PROJECT_NAME (comment 3): verified none of the three caller compose.env files set COMPOSE_PROJECT_NAME, COMPOSE_FILE, COMPOSE_PROFILES, or DOCKER_HOST — they carry only app secrets + a shared common block. So op run was never injecting a compose-behavior var; project naming defaults to the stack-dir basename for both up and the now-unwrapped down/ps/logs. Documented this in the teardown comment.
  • Dense comment (comment 1): tightened to a numbered 8-line note and folded in the project-naming rationale (net shorter).
  • Duplicated diagnostics helper (comment 2): valid, but pre-existing and out of scope for this fix. The dump_failed_stack triplication is deliberate — those jobs don't check out compose-workflow on the runner (noted inline), so a shared function isn't in scope without a composite-action refactor. Tracking as a follow-up.

@owine
owine merged commit 0ca7343 into main Jul 9, 2026
3 checks passed
@owine
owine deleted the fix/teardown-op-run-coupling branch July 9, 2026 22:36
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