Skip to content

feat(deploy): per-stage .deployignore semantics + --force flag#201

Open
mattcarranza10 wants to merge 1 commit into
mainfrom
feat/deployignore-per-stage
Open

feat(deploy): per-stage .deployignore semantics + --force flag#201
mattcarranza10 wants to merge 1 commit into
mainfrom
feat/deployignore-per-stage

Conversation

@mattcarranza10

Copy link
Copy Markdown
Contributor

Description

Bring the draft deploy:* commands in line with the per-stage .deployignore semantics that CI uses (scripts/deploy/check_deploy_ignore.sh in the api repo, introduced in api#6426) and add a --force flag so engineers can still trigger a manual local deploy when a stage is otherwise skipped.

Motivated by igaming, igaming-bff, and igaming-live: those services ship a .deployignore containing dev to silence the legacy auto-redeploy on push to main, but draft deploy:dev was reading the file with the old blunt semantics ("file present → skip everything"), so even manual local dev deploys via draft were no-ops while still printing [SUCCESS].

No new dependencies.

Task Context

What is the current behavior?

internal/actions/deploy/service.go::validateServiceDir (and the same call in function.go) treats any .deployignore as a hard skip for the service, regardless of stage. As a result:

  • Manual draft deploy:dev igaming-bff (and the equivalent deploy:func:dev) silently skips with Skipping <path>: .deployignore found and the run still terminates as a [SUCCESS].
  • Per-stage .deployignore (e.g. content dev) is not honoured — every stage gets blocked, not just the listed one.
  • There is no escape hatch: the only way to deploy is to remove or rename the file.

What is the new behavior?

.deployignore is now interpreted exactly like CI:

  • Missing → deploy.
  • Empty / whitespace only → skip every stage (preserves the legacy blunt behaviour for callers that still rely on it).
  • Has content → one stage per line, case-insensitive; the deploy is skipped only when the current stage matches a listed line.

A new --force flag on deploy:dev, deploy:prod, deploy:feature, deploy:func:dev, deploy:func:prod, and deploy:func:feature bypasses the .deployignore check entirely (the serverless.yml existence check still runs).

The skip log message now reports the matched stage and the override hint, e.g.:

Skipping /repo/services/igaming-bff: stage "dev" listed in .deployignore (use --force to override)

Additional Context

  • New helper: internal/actions/deploy/deployignore.go::shouldSkipForStage(absPath, stage) (skip bool, reason string, err error).
  • validateServiceDir was narrowed to a pure serverless.yml existence check so that --force can bypass the skip without bypassing the structural validation.
  • DeployService and DeployFunction gained a force bool parameter; the cobra layer wires --force through.
  • Behavior unchanged for services without a .deployignore and for services with an empty .deployignore (they still skip every stage, matching the CI script).
  • Companion file in api: services/igaming-bff/.deployignore (and the other igaming services) — content dev. After this PR, draft deploy:dev igaming-bff will skip with a clear stage-scoped message and --force will deploy; draft deploy:prod igaming-bff will deploy without prompting.

Checklist

  • go build ./...
  • go vet ./...
  • revive -config revive.toml -formatter friendly ./internal/actions/deploy/... ./cmd/commands/deploy/...
  • Manual smoke test against an api service with a stage-scoped .deployignore (planned post-merge once a release ships).

🤖 Generated with Claude Code

Match the per-stage skip logic from the api repo's
scripts/deploy/check_deploy_ignore.sh and add a --force flag so manual
local deploys can bypass the skip when needed.

.deployignore is now interpreted as:
  - missing                -> deploy
  - empty/whitespace only  -> skip every stage (legacy blunt behaviour)
  - has content            -> one stage per line, case-insensitive; skip
                              when the current stage matches a listed one

Previously any .deployignore file caused a blunt skip for every stage,
so services that opted into auto-deploy v2 with a stage-scoped
.deployignore (e.g. igaming with "dev") could not be deployed via
draft to any environment.

The skip log now reports the matched stage and reminds the user about
--force, e.g. "Skipping <path>: stage \"dev\" listed in .deployignore
(use --force to override)".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.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