Release Automation: Phase 1 (release-please) + Phase 2 (Public Registry)
INVEST User Stories — terraform-aws
Product Owner Coordination Log: tmp/terraform-aws/coordination-logs/product-owner-2026-02-28-release-please-phase1.json
CA Coordination Log: tmp/terraform-aws/coordination-logs/cloud-architect-2026-02-28-release-management.json
Agreement: 97% (PO) / 96% (CA)
Sprint Target: v1.2.0 (Phase 1) | Post-v2.0.0 (Phase 2)
5W1H — Phase 1: release-please Adoption
| Dimension | Answer |
|---|---|
| WHO | infrastructure-engineer (implementation) + meta-engineering-expert (ADLC gate validation) + HITL (Release PR merge) |
| WHAT | .github/workflows/release-please.yml, release-please-config.json, .release-please-manifest.json, .commitlintrc.json, Taskfile release:* tasks, BUG-CI-001 fix |
| WHEN | This sprint — before v1.2.0 tag push |
| WHERE | terraform-aws repo: .github/workflows/, repo root JSON configs, Taskfile.yml |
| WHY | Eliminate VERSION drift (root vs module), prevent tag collisions (BUG-REG-002 occurred), automate CHANGELOG, provide HITL gate via PR merge (stronger audit trail than CLI tag) |
| HOW | google-github-actions/release-please-action@v4 + conventional commits + commitlint + existing registry-publish.yml unchanged |
5W1H — Phase 2: Public Registry Thin-Wrapper Repos
| Dimension | Answer |
|---|---|
| WHO | cloud-architect (architecture + ADR-002 Phase 2 activation) + infrastructure-engineer (repos + sync workflow) + HITL (repo creation, OAuth, PAT) |
| WHAT | Separate repos per ADR-002: terraform-aws-iam-identity-center, terraform-aws-ecs-platform, terraform-aws-web. GitHub Actions cross-repo sync. |
| WHEN | Post-v2.0.0 — when modules stabilize. Target: Q3 2026. |
| WHERE | GitHub org nnthanh101/, registry.terraform.io, .github/workflows/registry-sync.yml in monorepo |
| WHY | Public Terraform Registry requires one repo per module (naming: terraform-<PROVIDER>-<NAME>). ADR-002 confirmed. |
| HOW | Thin wrapper: main.tf calls monorepo source at pinned tag. Sync workflow copies files + creates tag on module tag push. |
WSJF Priority Ranking
| Rank | Story | WSJF Score | Effort | Phase | Action |
|---|---|---|---|---|---|
| 1 | US-RP-001 Commitlint | 24.0 | 0.5d | Phase 1 | Ship first |
| 2 | US-RP-003 BUG-CI-001 | 24.0 | 0.5d | Phase 1 | Ship alongside US-RP-001 |
| 3 | US-RP-002 release-please | 14.0 | 1.0d | Phase 1 | Ship after commitlint advisory |
| 4 | US-RP-004 Taskfile tasks | 7.3 | 1.5d | Phase 1 | Ship alongside/after US-RP-002 |
| 5 | US-RP-005 Registry iam-ic | 1.4 | 5.0d | Phase 2 | Defer post-v2.0.0, split first |
| 6 | US-RP-006 Registry ecs+web | 0.6 | 8.0d | Phase 2 | Defer — modules not built yet |
Phase 1 total effort: 3.5 days
US-RP-001: Conventional Commit Enforcement via commitlint
INVEST Score: 6/6 — PASS
As the HITL platform engineer,
I want all commits to the terraform-aws repository to be validated
against conventional commit format (feat:/fix:/chore:/docs:/test:/refactor:/security:)
via commitlint in GitHub Actions
so that release-please can derive accurate semver bumps
and generate meaningful CHANGELOGs.
INVEST Breakdown
| Criterion | Score | Evidence |
|---|---|---|
| Independent | 1 | Standalone PR — does not modify registry-publish.yml or release-please files |
| Negotiable | 1 | Enforcement mode: advisory 14 days → blocking. Scope: PR commits vs push |
| Valuable | 1 | Prerequisite gate for all release-please value. KPI: 100% conventional commits on main within 30 days |
| Estimable | 1 | 0.5 day. .commitlintrc.json ~10 lines, CI step 3 lines |
| Small | 1 | 2 files + 1 CI step. Hours of effort |
| Testable | 1 | Exit codes verifiable: valid commit → 0, free-form commit → 1 |
Acceptance Criteria
AC-RP-001-1: Valid conventional commit passes
- Given commit message
fix: correct IAM path lookup in iam-identity-center locals.tf - When commitlint GitHub Actions check runs on a PR targeting main
- Then check exits 0 with PASSED status
AC-RP-001-2: Non-conventional commit blocked
- Given commit message
Github Actions CI/CD + InfraCost + Checkov APRA+FOCUS tag(current style) - When commitlint check runs
- Then check exits 1 with
type may not be empty— non-compliant commit blocked
AC-RP-001-3: Custom security type accepted
- Given commit message
security: remediate checkov CKV_AWS_58 finding - When commitlint check runs
- Then check exits 0 — custom type is allowed per
.commitlintrc.json
AC-RP-001-4: Breaking change triggers MAJOR bump signal
- Given commit message
feat!: remove sso_users_yaml variable (BREAKING CHANGE) - When commitlint check runs
- Then check exits 0 and release-please will derive MAJOR bump for next Release PR
Definition of Done
-
.commitlintrc.jsonat repo root with types:feat, fix, chore, docs, test, refactor, security, ci, build - commitlint step added to
ci.yml(advisory mode: exit 0 with warning for 14 days) -
CONTRIBUTING.mdsection: Commit Message Convention with examples - Evidence:
tmp/terraform-aws/test-results/commitlint-validation-2026-02-28.log
Agent: infrastructure-engineer | Reviewer: meta-engineering-expert | HITL gate: Approve type list
US-RP-002: release-please Workflow — Release PR Generation
INVEST Score: 6/6 — PASS
As the HITL platform engineer,
I want a release-please GitHub Actions workflow to automatically create
or update a Release PR on every push to main
so that I can review the proposed VERSION bump and CHANGELOG content,
then merge to trigger the git tag —
eliminating manual VERSION file editing and manual tag creation.
INVEST Breakdown
| Criterion | Score | Evidence |
|---|---|---|
| Independent | 1 | New file — does not modify registry-publish.yml or ci.yml |
| Negotiable | 1 | Token strategy (GITHUB_TOKEN vs PAT), single vs multi-package config |
| Valuable | 1 | Eliminates manual git tag push (BUG-REG-002 root cause). KPI: 0 tag collisions/quarter, ~30 min → ~5 min HITL toil per release |
| Estimable | 1 | 1 day. release-please-action@v4 well-documented for terraform-module type |
| Small | 1 | 3 new files (~60 lines total). Single sprint PR |
| Testable | 1 | Release PR created after feat: commit; VERSION bumped in both files; HITL merge → v-tag → CI fires |
Acceptance Criteria
AC-RP-002-1: Release PR created after feat: commit
- Given
feat: add ecs-platform module skeletonis merged to main - When release-please workflow runs
- Then Release PR titled
chore(main): release iam-identity-center 1.2.0is created within 5 minutes, showing VERSION bumped from 1.1.0 to 1.2.0 in bothVERSIONandmodules/iam-identity-center/VERSION
AC-RP-002-2: HITL merge triggers full release chain
- Given Release PR exists with correct VERSION and CHANGELOG content
- When HITL reviews and merges the Release PR
- Then release-please creates git tag
v1.2.0,registry-publish.ymlfires, GitHub Releasev1.2.0created, TFC ingests within 10 minutes
AC-RP-002-3: PATCH bump from fix: commits
- Given multiple
fix:commits pushed to main, nofeat:commits - When release-please workflow runs
- Then Release PR proposes PATCH bump (1.1.0 → 1.1.1) — correct semver derivation
AC-RP-002-4: Idempotency — no duplicate PRs
- Given Release PR exists and HITL has not merged it
- When additional
feat:commits are pushed to main - Then release-please UPDATES the existing PR (no duplicate created)
AC-RP-002-5: MAJOR bump from breaking change
- Given
feat!: BREAKING CHANGE remove deprecated variablemerged to main - When release-please workflow runs
- Then Release PR proposes MAJOR bump (1.1.0 → 2.0.0)
Definition of Done
-
.github/workflows/release-please.ymlcreated (trigger: push to main) -
release-please-config.jsonat repo root (type:terraform-module,extra-files: [VERSION, modules/iam-identity-center/VERSION]) -
.release-please-manifest.jsonwith{".": "1.1.0"} - TOKEN strategy confirmed and tested
-
registry-publish.ymlverified: NO CHANGES needed - ADR-022 created:
DevOps-TechDocs/docs/docs/terraform-aws/adr/ADR-022-release-management-automation.md - Evidence:
tmp/terraform-aws/test-results/release-please-validation-2026-02-28.log
Agent: infrastructure-engineer (files) + meta-engineering-expert (ADLC gate review) | HITL gate: Token strategy approval + first Release PR merge
US-RP-003: Fix CI Test Evidence Path (BUG-CI-001)
INVEST Score: 6/6 — PASS
As the HITL platform engineer,
I want the Tier 1 Snapshot Tests CI job to reliably write test results
to tmp/terraform-aws/test-results/ and upload them as artifacts
so that I always have evidence of test passage for every release tag —
and the CI job fails correctly when tests fail.
Root Cause
# BROKEN — PIPESTATUS[0] on separate line reads echo's exit code, not task's
task test:tier1 2>&1 | tee tmp/terraform-aws/test-results/tier1-snapshot.log
echo "exit_code=${PIPESTATUS[0]}" >> tmp/terraform-aws/test-results/tier1-summary.txt
exit ${PIPESTATUS[0]} # Always exits 0
# FIXED — capture immediately after pipe
task test:tier1 2>&1 | tee tmp/terraform-aws/test-results/tier1-snapshot.log
TASK_EXIT=${PIPESTATUS[0]}
echo "exit_code=${TASK_EXIT}" >> tmp/terraform-aws/test-results/tier1-summary.txt
exit ${TASK_EXIT}
INVEST Breakdown
| Criterion | Score | Evidence |
|---|---|---|
| Independent | 1 | registry-publish.yml change only — no other file dependencies |
| Negotiable | 1 | Inline fix vs extract to scripts/ci-test.sh — both valid |
| Valuable | 1 | ADLC anti-NATO requires test evidence. KPI: 100% of release CI runs produce non-empty test-results artifact |
| Estimable | 1 | 0.5 day. Known shell pattern |
| Small | 1 | 3-5 line change in one file |
| Testable | 1 | Artifact upload success/failure and test failure propagation are objectively verifiable |
Acceptance Criteria
AC-RP-003-1: Artifact upload succeeds
- Given tag push triggers
registry-publish.ymland tests pass - When Tier 1 Snapshot Tests job completes
- Then Upload step shows
Artifact test-results created successfully— noNo files were foundwarning
AC-RP-003-2: Test failure propagates correctly
- Given
task test:tier1exits 1 (an assertion fails) - When the CI job runs
- Then CI job exits 1, release job is NOT triggered, workflow shows FAIL on test job
AC-RP-003-3: Log content is meaningful
- Given tests run
- When
tier1-snapshot.logis uploaded - Then Log contains
terraform test -verboseoutput including=== Tier 1 Summary ===section
Definition of Done
-
registry-publish.ymltest step: PIPESTATUS captured inline - Local validation:
tier1-snapshot.lognon-empty aftertask test:tier1 - Evidence:
tmp/terraform-aws/evidence/bug-ci-001-fix-validation-2026-02-28.md
Agent: infrastructure-engineer | Reviewer: qa-engineer | HITL gate: Confirm artifact upload non-empty in CI
US-RP-004: Taskfile release:* Helper Tasks
INVEST Score: 6/6 — PASS
As the HITL platform engineer,
I want Taskfile tasks (release:bump, release:tag-check,
release:changelog-prepare, release:verify)
to complement release-please for local pre-flight checks and fallback scenarios
so that I can verify state locally before triggering any release action.
INVEST Breakdown
| Criterion | Score | Evidence |
|---|---|---|
| Independent | 1 | Taskfile additions — independent of release-please.yml |
| Negotiable | 1 | release:tag-check is highest value; others optional. Ship in priority order |
| Valuable | 1 | Prevents BUG-REG-002 recurrence. KPI: 0 tag collisions/quarter |
| Estimable | 1 | 1.5 days: tag-check (0.25d), bump (0.5d), changelog-prepare (0.25d), verify (0.5d) |
| Small | 1 | 4 tasks, ~80-100 lines shell. One sprint |
| Testable | 1 | All tasks testable via exit codes and file content |
Acceptance Criteria
AC-RP-004-1: Tag collision detection
- Given
v1.1.0tag exists in remote - When HITL runs
task release:tag-check VERSION=1.1.0 - Then Task exits 1 with
FAIL: tag v1.1.0 already exists in remote — bump version before tagging
AC-RP-004-2: Atomic VERSION bump
- Given root
VERSION = 1.1.0,modules/iam-identity-center/VERSION = 1.1.0 - When HITL runs
task release:bump TYPE=minor - Then Both files show
1.2.0— atomically updated
AC-RP-004-3: Multi-module bump (future)
- Given
ecs-platformmodule added atmodules/ecs-platform/VERSION - When
task release:bump TYPE=minorruns - Then All
modules/*/VERSIONfiles bumped — no manual per-module intervention
AC-RP-004-4: Post-release verification
- Given
v1.2.0tag pushed,registry-publish.ymlcompleted - When HITL runs
task release:verify VERSION=1.2.0 - Then Task confirms: GitHub Release
v1.2.0exists, TFC version status = healthy (advisory if no TFC token)
Definition of Done
-
Taskfile.yml:task release:tag-check(git ls-remote existence check) -
Taskfile.yml:task release:bump TYPE=patch|minor|major(semver arithmetic, updates allmodules/*/VERSION) -
Taskfile.yml:task release:changelog-prepare(writes[vX.Y.Z] - YYYY-MM-DDheader toCHANGELOG.md) -
Taskfile.yml:task release:verify(gh release view + advisory TFC check) - Evidence:
tmp/terraform-aws/evidence/release-tasks-validation-2026-02-28.md
Agent: infrastructure-engineer | Reviewer: meta-engineering-expert | HITL gate: Semver arithmetic correctness review
US-RP-005: Public Registry Thin-Wrapper — iam-identity-center
INVEST Score: 5/6 — ACCEPTABLE (split required before sprint scheduling)
As a Terraform community consumer,
I want to install the iam-identity-center module via the public Terraform Registry
address (registry.terraform.io/oceansoft/iam-identity-center/aws)
so that I can reference the module without knowledge
of the private monorepo structure.
This story requires HITL approval for GitHub repo creation, registry.terraform.io OAuth, and a PAT with cross-repo write scope. Schedule only after iam-identity-center reaches v2.0.0 stable.
INVEST Breakdown
| Criterion | Score | Evidence |
|---|---|---|
| Independent | 1 | Per-module — terraform-aws-iam-identity-center independent of ecs-platform/web |
| Negotiable | 1 | Timeline negotiable. Sync mechanism negotiable. iam-identity-center-only scope for Phase 2a |
| Valuable | 1 | Public registry discoverability is stated product goal (ADR-002). KPI: module available on registry.terraform.io within 24h of monorepo tag push |
| Estimable | 1 | 5 days: repo creation (0.5d), thin wrapper files (1d), sync workflow (2d), registry connection (0.5d), testing (1d) |
| Small | 0 | NOT SMALL — 5 days, multi-system. Must split into US-RP-005a + US-RP-005b |
| Testable | 1 | terraform init with registry source succeeds; sync fires within 10 min of monorepo tag |
Split Recommendation:
- US-RP-005a: Create
terraform-aws-iam-identity-centerthin wrapper repo with Terraform files (~3 days) - US-RP-005b: GitHub Actions cross-repo sync workflow in monorepo (~2 days, depends on 005a)
Acceptance Criteria
AC-RP-005-1: Registry source resolves
- Given consumer has
source = "registry.terraform.io/oceansoft/iam-identity-center/aws"version = "~> 2.0" - When they run
terraform init - Then Module downloads successfully — no authentication required
AC-RP-005-2: Sync automation fires on monorepo tag
- Given
v2.1.0tag pushed to terraform-aws monorepo - When
registry-sync.ymlworkflow runs - Then
terraform-aws-iam-identity-centerrepo hasv2.1.0tag within 10 minutes
AC-RP-005-3: Consumer state shows registry address
- Given consumer deploys via registry source
- When they inspect state file
- Then Source is
registry.terraform.io/oceansoft/iam-identity-center/aws(not GitHub URL)
HITL Required
- GitHub repo creation:
nnthanh101/terraform-aws-iam-identity-center - registry.terraform.io OAuth connection
- PAT with cross-repo write scope approval
Agents: cloud-architect (architecture + ADR-002 Phase 2 activation) + infrastructure-engineer (files + sync workflow) + meta-engineering-expert (consumer acceptance test)
US-RP-006: Public Registry Thin-Wrappers — ecs-platform + web
INVEST Score: 4/6 — DEFERRED (blocked by prerequisites)
As a Terraform community consumer,
I want the ecs-platform and web modules available on the public
Terraform Registry so that the complete oceansoft module suite
is discoverable and installable from a single registry namespace.
ecs-platform and web modules do not yet exist. Cannot create registry wrappers for non-existent modules. Dependency: ecs-platform v1.0.0 + web v1.0.0 in monorepo.
WSJF: 0.6 — Lowest priority. Do not schedule until module prerequisites are met.
Agent Delegation Matrix
| Story | Primary Agent | Secondary | Reviewer | HITL Gate |
|---|---|---|---|---|
| US-RP-001 | infrastructure-engineer | — | meta-engineering-expert | Approve .commitlintrc.json type list |
| US-RP-002 | infrastructure-engineer | meta-engineering-expert | product-owner + cloud-architect | Token strategy + first Release PR merge |
| US-RP-003 | infrastructure-engineer | — | qa-engineer | Confirm artifact upload non-empty in CI |
| US-RP-004 | infrastructure-engineer | — | meta-engineering-expert | Semver arithmetic correctness review |
| US-RP-005 | cloud-architect | infrastructure-engineer | meta-engineering-expert | Repo creation + OAuth + PAT approval |
| US-RP-006 | cloud-architect | infrastructure-engineer | meta-engineering-expert | Module roadmap approval + repo creation x2 |
Quality Gates — Sprint Exit Criteria
All of the following must pass before v1.2.0 release:
- US-RP-001: commitlint exits 0 on valid commit, exits 1 on free-form commit — PASS
- US-RP-002: First Release PR created, HITL merges,
v1.2.0tag created, TFC ingests — PASS - US-RP-003: Tier 1 Snapshot Tests artifact upload shows no
No files were foundwarning — PASS - US-RP-004:
task release:tag-check VERSION=1.1.0exits 1;task release:bump TYPE=minorproduces 1.2.0 — PASS -
modules/iam-identity-center/CHANGELOG.mdcontains[1.1.0]entry — ACTIVE DEFECT, HITL must fix - ADR-022 merged to
DevOps-TechDocs/docs/docs/terraform-aws/adr/ -
task sprint:validatePASS on Legal-Compliance branch - All evidence artifacts in
tmp/terraform-aws/(coordination logs + test results + evidence files)
Risk Flags
| ID | Risk | Probability | Impact | Mitigation |
|---|---|---|---|---|
| RISK-RP-001 | Branch protection blocks GITHUB_TOKEN for Release PR | MEDIUM | MEDIUM | Create RELEASE_PLEASE_PAT, store as Actions secret |
| RISK-RP-002 | Conventional commit adoption failure after initial adoption | LOW | LOW | commitlint advisory 14d → blocking; HITL can edit VERSION in Release PR |
| RISK-RP-003 | modules/iam-identity-center/CHANGELOG.md missing v1.1.0 entry | CERTAIN | MEDIUM | HITL immediate action required before sprint exit |
| RISK-RP-004 | TFC webhook fires before GitHub Release created (timing race) | LOW | LOW | registry-publish.yml idempotency guard already present; TFC retries |
| RISK-RP-005 | Phase 2 sync automation fails silently — thin wrappers fall behind | MEDIUM | HIGH | Mandatory status checks + failure notifications in registry-sync.yml |
Immediate Actions Blocking Sprint
- HITL (BLOCKING): Add
[1.1.0]entry tomodules/iam-identity-center/CHANGELOG.md - HITL (HIGH): Confirm token strategy — GITHUB_TOKEN acceptable or PAT required for release-please PR creation
- HITL (HIGH): Approve ADR-022 scope and commission infrastructure-engineer for US-RP-001 + US-RP-003 first PR
Evidence: tmp/terraform-aws/coordination-logs/product-owner-2026-02-28-release-please-phase1.json
Constitutional compliance: ADLC Principle I (Acceptable Agency) — HITL gates preserved throughout