Skip to content

Decoupling#89

Merged
hyunsies merged 25 commits intomainfrom
decoupling
May 6, 2026
Merged

Decoupling#89
hyunsies merged 25 commits intomainfrom
decoupling

Conversation

@ngjinshan
Copy link
Copy Markdown
Collaborator

Description

Brief description of the change and the problem it solves.

Type of change

  • Bug fix
  • New resource type support
  • Security improvement
  • Documentation update

Testing

  • Tested end-to-end in a real AWS account (or CI E2E will cover this)
  • No false positives observed
  • CloudWatch logs reviewed for errors

Checklist

  • CloudFormation template is valid (cfn-lint passes — checked by CI)
  • IAM permissions follow least-privilege (only tag actions added)
  • If adding a new service handler: corresponding resource added to .github/scripts/resource_groups/ for E2E coverage
  • CHANGELOG.md updated

CI Notes

Layer 1 (lint) runs immediately on every PR — ~1 min.
Layer 2 (E2E) runs when map2-auto-tagger-optimized.yaml or configurator.html changes — ~37 min across 7 AWS accounts. No AWS credentials needed.
If Layer 2 fails, download verification-report.json from the Actions run for details.

ngjinshan added 10 commits May 4, 2026 11:33
Add build script that reassembles configurator.html from src/ parts.
Currently a trivial split (CSS, HTML skeleton, JS monolith) that
produces a byte-identical output to the original. This establishes
the round-trip verification baseline for subsequent extraction phases.
Split the monolithic JS into separate files:
- src/js/i18n/all.js — translations + engine (~2,463 lines)
- src/js/services/registry.js — event names, sources, permissions (~185 lines)
- src/js/deploy/template-main.js — CFN template generator (~3,113 lines)
- src/js/deploy/template-org.js — org/per-account templates (~229 lines)
- src/js/deploy/instructions.js — instructions generator (~83 lines)
- src/js/deploy/script-deploy.js — deploy.sh generator (~1,084 lines)

Build output remains byte-identical to the original.
Split constants (TEMPLATE_VERSION, VERSION_HISTORY, renderVersionHistory)
into src/js/constants.js. Remaining flow logic stays in app-pre.js for
now — per-flow splitting will be done in a subsequent pass.

Current structure:
- src/css/styles.css (183 lines)
- src/html/configurator.html (964 lines)
- src/js/constants.js (345 lines)
- src/js/app-pre.js (1,786 lines) — all flow logic
- src/js/i18n/all.js (2,463 lines) — translations + engine
- src/js/services/registry.js (185 lines)
- src/js/deploy/template-main.js (3,113 lines)
- src/js/deploy/instructions.js (83 lines)
- src/js/deploy/template-org.js (229 lines)
- src/js/deploy/script-deploy.js (1,084 lines)
- src/js/app-post.js (92 lines) — output/download

Build output remains byte-identical to the original.
Split app-pre.js into:
- src/js/shared/ui.js (40 lines) — selectMode, step navigation
- src/js/editor/editor-flow.js (795 lines) — editor flow
- src/js/upgrade/upgrade-flow.js (124 lines) — upgrade flow
- src/js/delete/delete-flow.js (408 lines) — delete flow
- src/js/deploy/deploy-flow.js (419 lines) — deploy flow UI

Output is functionally identical (same byte count, all functions
present). Function order differs from the original since the
interleaved flows are now grouped by module.
- Split i18n/all.js into 7 locale files + engine.js
- Extract Lambda Python handler (2,082 lines) to src/templates/lambda-handler.py
- Rename app-post.js → app.js

Build output is functionally identical (all functions and i18n keys
present, 216 bytes larger due to variable wrapper declarations).
Break the monolithic ALL_EVENT_NAMES/ALL_SOURCES/TAGGING_PERMISSIONS
arrays into ~80 per-service files (e.g., ec2.js, rds.js, s3.js).
Each file declares its source, events, and permissions.
index.js aggregates them into the three flat arrays.

Build script auto-discovers service files via directory listing.
Adding a new service = drop a new .js file in src/js/services/.

Includes README.md documenting the per-service format.
- scripts/verify-build.js — 13 sanity checks on built HTML
- tests/unit/services.test.js — 10 tests (service module format, no duplicate sources)
- tests/unit/i18n.test.js — 13 tests (locale files, engine functions)
- tests/unit/build.test.js — 7 tests (built output completeness)
- tests/unit/lambda.test.js — 5 tests (Python handler structure)
- vitest.config.js + package.json scripts (build, test, verify)

35 tests, all passing.
- .github/workflows/build.yml — test → build → verify on PRs,
  auto-commit built output on main
- Update generate_deploy_sh.js to use build/configurator.html
- Replace root configurator.html with redirect to build/
- template-main.js now uses ${LAMBDA_HANDLER_CODE} placeholder
  (3,113 → 1,032 lines; Python lives in src/templates/lambda-handler.py)
- Build script reads .py, indents for YAML, injects into JS bundle
- README updated: paths, Components table, new Development section
- All 35 tests passing, build verification clean
@ngjinshan ngjinshan requested a review from hyunsies as a code owner May 4, 2026 06:03
Comment on lines +11 to +29
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx vitest run
- run: node scripts/build.js
- run: node scripts/verify-build.js

- name: Commit built configurator.html
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add build/configurator.html
git diff --cached --quiet || git commit -m "build: regenerate configurator.html [skip ci]"
git push
ngjinshan added 15 commits May 4, 2026 14:17
All lint scripts and workflows now read from build/configurator.html
instead of the root (which is now a redirect). Added Node.js setup +
build step to 6 lint jobs so the built file exists before linting.
Replace 6 redundant per-job builds with one shared build-configurator
job. Lint jobs that need build/configurator.html now declare
needs: build-configurator and download the artifact.
E2E workflow now builds configurator.html from src/ before
Playwright generates deploy.sh. Ensures E2E always tests the
current source, not a potentially stale committed build.
After per-service split, permissions are in individual service module
objects rather than a single TAGGING_PERMISSIONS array. Updated
sync-check.py to scan the entire built HTML for IAM action patterns
instead of searching only within the TAGGING_PERMISSIONS block.
Updated OVERVIEW.md, INSTRUCTIONS.md, LIMITATIONS.md, README.md,
VERSIONING.md, and design-reconciliation.md. CHANGELOG.md left
unchanged (historical references).
Covers directory layout, build process, and how to add new services,
locales, flows, and modify the Lambda handler.
Avoids false editor errors from HTML comments inside style/script tags.
Move build output from build/configurator.html back to the root so
customers find it in the same place as before. Delete build/ directory.

Updated: build.js, verify-build.js, build.test.js, generate_deploy_sh.js,
all lint scripts, all workflows, all docs, .gitignore.
Add scripts/build-yaml.js that calls the same generateMainTemplate()
to produce standalone YAML. Accepts --config JSON and --output path.

E2E scope tests and deploy-single now generate their own YAML via
build-yaml.js instead of deploying map2-auto-tagger-optimized.yaml.
Each test bakes its specific config (MPE, VPC IDs, dates) directly.

The standalone YAML and sync-check are kept for now — once E2E passes
with the new path, they can be removed in a follow-up commit.
Delete map2-auto-tagger-optimized.yaml, sync-check.py, and
.github/sync/ (canonical permissions file). All lint jobs now
depend on build-configurator and use the generated configurator.yaml.

One source of truth (src/), two build outputs (HTML + YAML),
zero drift possible.
The download-artifact insertion collided with a checkout step that
had fetch-depth: 0, producing two 'with:' blocks on the same step.
- cfn-lint: add -I W to ignore warnings (unused params expected with
  baked values in generated YAML)
- generate_iam.py: load_canonical() now extracts permissions from
  configurator.yaml instead of the deleted tagging-permissions.txt
Bug 1: AutoTaggerFunction was missing DeadLetterConfig pointing to
EventDLQ. Pre-existing gap between standalone YAML and configurator,
now fixed in template-main.js.

Bug 2: UUID strip regex was lost during lambda-handler.py extraction.
StackSet instance stacks have a UUID suffix that must be stripped
before comparing MPE IDs in the peer detector.
@hyunsies hyunsies merged commit 5f9d14b into main May 6, 2026
18 checks passed
@hyunsies hyunsies deleted the decoupling branch May 6, 2026 00:41
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.

3 participants