Skip to content

feat(deploy): add shared-networks input for cross-stack networks - #100

Merged
owine merged 2 commits into
mainfrom
feat/shared-networks
Oct 10, 2026
Merged

owine merged 2 commits into
mainfrom
feat/shared-networks

Conversation

@owine

@owine owine commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Why

piwine's Traefik-routed stacks all join dockge_default, a network owned by the dockge Compose project (being retired). A project-owned shared network makes deploy order load-bearing on a fresh host, and the owner's down tries to remove a network every other stack is attached to.

What

  • New optional input shared-networks (space-separated, default empty → no-op for existing callers).
  • scripts/deployment/ensure-shared-networks.sh: idempotently creates each missing network as a plain bridge labelled com.compose-workflow.shared=true; warns if an existing one is owned by a Compose project; validates names.
  • Runs in deploy (after the live-tree update, before dockge/stacks) and rollback (before either rollback mode's up).
  • Both jobs check out compose-workflow at job.workflow_sha, gated on the input. Deploy's target checkout runs git clean -ffdx, so prepare's .compose-workflow never survives into it; rollback had no checkout.
  • docker-prune network prune now skips the shared label.
  • README/CLAUDE.md docs.

Testing

  • yamllint --strict, shellcheck clean. Local actionlint only flags the pre-existing job.workflow_sha (older local binary; also on prepare's existing checkout).
  • Script exercised against a local Docker daemon: create, idempotent re-run, invalid name (rc=1), Compose-owned warning, survives the label-filtered prune, no-arg no-op.

First consumer: docker-piwine (shared-networks: "proxy backup"), after Renovate bumps its pin.

Summary by Sourcery

Support Compose stacks that rely on external cross-stack networks by provisioning and preserving shared networks throughout deployment and rollback.

New Features:

  • Add an optional shared-networks deployment input for creating cross-stack bridge networks before deployments and rollbacks.

Bug Fixes:

  • Prevent shared networks from being removed by post-deployment Docker network pruning.

Enhancements:

  • Create and reuse shared networks independently of Compose projects, with validation and warnings for unsafe pre-existing networks.

Deployment:

  • Ensure shared networks are available before stack startup in both deploy and rollback workflows, using workflow-pinned scripts.

Documentation:

  • Document shared-network configuration, lifecycle, and workflow behavior in the README and CLAUDE.md.

Stacks that talk across Compose projects (Traefik and every routed service)
have relied on a network owned by one project: piwine's `dockge_default`
belongs to the dockge stack. That makes deploy order load-bearing on a fresh
host and lets the owner's `down` try to remove a network every other stack is
attached to.

`shared-networks` lists bridge networks that deploy and rollback create (if
missing) before any `up`, via scripts/deployment/ensure-shared-networks.sh.
They belong to no Compose project, and a `com.compose-workflow.shared` label
exempts them from docker-prune's network prune. Both jobs check out the
scripts at job.workflow_sha only when the input is set: deploy's own target
checkout runs `git clean -ffdx`, so prepare's copy never survives into it, and
rollback had no checkout at all.

Empty by default, so existing callers are unaffected.
@sourcery-ai

sourcery-ai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

The PR adds an opt-in shared-network lifecycle: deploy and rollback provision validated, unowned bridge networks before stacks start, while a shared label preserves them from pruning; workflow checkout handling and project documentation are updated accordingly.

Sequence diagram for shared-network provisioning during deploy and rollback

sequenceDiagram
    participant Workflow
    participant ComposeWorkflow as compose-workflow checkout
    participant Ensure as ensure-shared-networks.sh
    participant Docker
    participant Stacks

    Workflow->>Workflow: Read shared-networks
    alt shared-networks is set
        Workflow->>ComposeWorkflow: Checkout at job.workflow_sha
        Workflow->>Ensure: Run with network names
        loop Each network
            Ensure->>Docker: network inspect
            alt Network missing
                Ensure->>Docker: network create --driver bridge --label
            else Network exists
                Ensure-->>Workflow: Reuse network
            end
        end
        Workflow->>Stacks: Start deploy or rollback stacks
    else shared-networks is empty
        Workflow->>Stacks: Continue without provisioning
    end
Loading

File-Level Changes

Change Details Files
Add optional shared-network provisioning to deployment and rollback workflows.
  • Expose a space-separated shared-networks workflow input with an empty default.
  • Pass the input into deploy and rollback jobs and run provisioning before any stack up.
  • Re-check out the pinned workflow repository in both jobs because deploy cleanup removes the prepare checkout and rollback previously had no checkout.
  • Keep existing callers behavior unchanged when the input is empty.
.github/workflows/deploy.yml
Implement idempotent, validated creation of externally shared Docker networks.
  • Validate network names before interacting with Docker.
  • Reuse existing networks and warn when Compose ownership metadata is present.
  • Create missing networks as unowned bridge networks with the shared-workflow label.
scripts/deployment/ensure-shared-networks.sh
Protect shared networks from post-deploy network pruning.
  • Filter docker network prune to exclude networks labelled com.compose-workflow.shared.
.github/workflows/deploy.yml
Document shared-network configuration and workflow behavior.
  • Document the input, external-network usage, label-based prune exemption, and deployment/rollback timing.
  • Update workflow/job and script inventories and current dockge guidance.
README.md
CLAUDE.md

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 found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path=".github/workflows/deploy.yml" line_range="971-972" />
<code_context>

+      # The checkout above cleans the workspace; re-fetch the scripts, pinned
+      # to this workflow's commit as in the prepare job.
+      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1  # v7.0.1
+        if: |
+          steps.skip-gate.outputs.skipped == 'false'
</code_context>
<issue_to_address>
**Rollback recovery stops before restoring prior state**

When the rollback helper checkout or shared-network validation or setup fails, the rollback job skips `Resolve rollback plan` and its recovery steps, leaving the failed target tree deployed and removed stacks offline.

Run rollback planning and restoration even when helper checkout or network setup fails, since recovery does not require network setup.

Also at `.github/workflows/deploy.yml:537`, `.github/workflows/deploy.yml:978-979`, `.github/workflows/deploy.yml:983`, `scripts/deployment/ensure-shared-networks.sh:29-32`.
</issue_to_address>

### Comment 2
<location path="scripts/deployment/ensure-shared-networks.sh" line_range="39" />
<code_context>
+    if [[ -n "$project" ]]; then
+      echo "::warning::shared network $net is owned by Compose project '$project'; its 'down' will try to remove it"
+    fi
+    log_success "$net exists"
+  else
+    docker network create --driver bridge --label "$SHARED_LABEL" "$net" >/dev/null
</code_context>
<issue_to_address>
**Shared networks disappear after pruning**

When a configured shared network already exists without the shared label and has no attached containers when post-deploy pruning runs, the ensure script logs success without making the reused network exempt from the label-filtered prune, so Docker removes it and later external Compose starts fail; recreating it as a plain bridge can also lose existing network configuration.

Ensure reused shared networks are protected from the label-filtered prune, either by applying the shared label or otherwise excluding them from pruning.

Also at `.github/workflows/deploy.yml:916`.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 2 findings to address first, and if the workflow or network handling is wrong, deployments may fail or create shared bridge networks that remain after reverting the change. The networks are bounded and can be inspected and removed manually, but reverting alone does not undo them.

Blocking findings: .github/workflows/deploy.yml:972, scripts/deployment/ensure-shared-networks.sh:39


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread .github/workflows/deploy.yml
Comment thread scripts/deployment/ensure-shared-networks.sh
…on unlabelled shared networks

Addresses Sourcery review on #100:
- rollback: continue-on-error on the scripts checkout and Ensure shared
  networks, so a failure there cannot skip the plan/restore steps.
- ensure-shared-networks.sh: warn when a pre-existing network lacks the
  shared label (prune would remove it while idle). Labels are immutable,
  so it is reused, never recreated automatically.
@owine
owine merged commit fc0c0e3 into main Oct 10, 2026
3 checks passed
@owine
owine deleted the feat/shared-networks branch October 10, 2026 04:26
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