Skip to content

feat: Floodgate DA Updates and Fixes#5763

Open
chrischrischris wants to merge 3 commits intostagefrom
da-floodgate
Open

feat: Floodgate DA Updates and Fixes#5763
chrischrischris wants to merge 3 commits intostagefrom
da-floodgate

Conversation

@chrischrischris
Copy link
Copy Markdown
Contributor

@chrischrischris chrischrischris commented Apr 2, 2026

Update to floodgate for DA.

  • Structure — Split floodgate.js; add floodgate-workflows.js and floodgate-render.js. Lit: org + email for access checks.
  • Config & access — Parse allAccessUsers, copyOnlyUsers, draftsAllowed, colors, promote-ignore sheet; evaluateFloodgateAccess (full / copy-only / drafts-only / blocked). Ignore empty promote-ignore rows; discard stale config if org/repo changes mid-fetch.
  • Paths — Wildcards, line-level invalid highlighting, AEM preview URL to repo path, reject -fg-* in source paths, sessionStorage for textarea, debounced access re-eval.
  • Workflows — Batched existence checks, promote-ignore from config + UI, confirmations for large jobs (>50) and destructive ops, cancel mid-run, retry includes preview/publish errors and normalizes FG to source paths.
  • Copy / promote — -fg-{color} (not hard-coded pink); search-replace uses selected color; Queue (max 100 concurrent) instead of fixed batches; options-object constructors; fix empty-path guard in copy.
  • HTTP / bulk actions — daFetch returns full Response on 401; preview/publish callbacks include original DA path.
  • UI / CSS — Tabbed flow, done summary with expandable errors, badge/list slug alignment for expand toggles, updated Floodgate + minor floodbox styles.
  • Tests — New floodgate.test.js; expanded floodgate-config.test.js; utils.test.js tweaks.

Config for floodgate is set in org/site/.milo/floodgate/config.json in the main repo.

Resolves: MWPW-189268

Test URLs:
https://da.live/app/adobecom/milo/tools/floodgate?ref=da-floodgate

@aem-code-sync
Copy link
Copy Markdown
Contributor

aem-code-sync bot commented Apr 2, 2026

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch.
In case there are problems, just click the checkbox below to rerun the respective action.

  • Re-sync branch
Commits

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

eslint

🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessInfoMessage'.

expect(el._accessInfoMessage).to.equal('Drafts only');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlocksFind'.

expect(el._accessBlocksFind()).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_configLoading'.

el._configLoading = true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlocksFind'.

expect(el._accessBlocksFind()).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_floodgateConfig'.

el._floodgateConfig = {};


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlocksFind'.

expect(el._accessBlocksFind()).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_floodgateConfig'.

const FloodgateConfig = el._floodgateConfig.constructor;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_floodgateConfig'.

el._floodgateConfig = Object.create(FloodgateConfig.prototype);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlockScope'.

el._accessBlockScope = 'all';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlocksFind'.

expect(el._accessBlocksFind()).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlockScope'.

el._accessBlockScope = 'paths';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlocksFind'.

expect(el._accessBlocksFind()).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlockScope'.

el._accessBlockScope = 'operation';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlocksFind'.

expect(el._accessBlocksFind()).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_floodgateConfig'.

el._floodgateConfig = new FC('org', 'repo', 'token');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_configLoading'.

el._configLoading = false;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlockScope'.

el._accessBlockScope = 'none';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_accessBlocksFind'.

expect(el._accessBlocksFind()).to.be.false;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgCopy';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgCopy';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_previewAfterCopy'.

el._previewAfterCopy = true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgPromote';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgPromote';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_publishAfterPromote'.

el._publishAfterPromote = true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgDelete';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

el._filesToProcess = ['/a', '/b', '/c'];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

expect(el._filesToProcess).to.deep.equal(['/a', '/c']);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_cancelled'.

expect(el._cancelled).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_showDialog'.

expect(el._showDialog).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_dialogType'.

expect(el._dialogType).to.equal('delete');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_dialogMessage'.

expect(el._dialogMessage).to.equal('Are you sure?');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_showDialog'.

expect(el._showDialog).to.be.false;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_dialogType'.

expect(el._dialogType).to.equal('');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_org'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_sourceRepo'.

el._sourceRepo = 'myrepo';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedColor'.

el._selectedColor = 'pink';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

el._filesToProcess = ['/myorg/myrepo/page'];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

el._filesToProcess = ['/myorg/myrepo/data.json'];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_org'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_sourceRepo'.

el._sourceRepo = 'myrepo';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedColor'.

el._selectedColor = 'blue';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

el._filesToProcess = ['/myorg/myrepo/page', '/myorg/myrepo/file.json'];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_floodgateConfig'.


🚫 [eslint] <object-curly-newline> reported by reviewdog 🐶
Unexpected line break after this opening brace.


🚫 [eslint] <object-curly-newline> reported by reviewdog 🐶
Unexpected line break before this closing brace.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promoteIgnorePaths'.

expect(el._promoteIgnorePaths).to.deep.equal(['/placeholders.json', '/metadata.json']);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_floodgateConfig'.


🚫 [eslint] <object-curly-newline> reported by reviewdog 🐶
Unexpected line break after this opening brace.


🚫 [eslint] <object-curly-newline> reported by reviewdog 🐶
Unexpected line break before this closing brace.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promoteIgnorePaths'.

expect(el._promoteIgnorePaths).to.deep.equal(['/my-page.html']);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_floodgateConfig'.

el._floodgateConfig = {};


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promoteIgnorePaths'.

expect(el._promoteIgnorePaths).to.deep.equal([]);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

el._filesToProcess = ['/org/repo/page.html', '/org/repo/placeholders.json', '/org/repo/other.html'];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promoteIgnorePaths'.

el._promoteIgnorePaths = ['/placeholders.json'];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

expect(el._filesToProcess).to.deep.equal(['/org/repo/page.html', '/org/repo/other.html']);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promoteIgnoreList'.

expect(el._promoteIgnoreList).to.deep.equal([


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

el._filesToProcess = ['/org/repo/summit25/page.html', '/org/repo/other.html'];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promoteIgnorePaths'.

el._promoteIgnorePaths = ['/summit25/'];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

expect(el._filesToProcess).to.deep.equal(['/org/repo/other.html']);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgCopy';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_copiedFilesCount'.

el._copiedFilesCount = 5;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_copiedErrorList'.

el._copiedErrorList = [{ href: '/a', status: 500 }];


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_copyDuration'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgCopy';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_previewAfterCopy'.

el._previewAfterCopy = true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_previewDuration'.

el._previewDuration = 5;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_copiedFilesCount'.

el._copiedFilesCount = 3;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_copyDuration'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_previewedFilesCount'.

el._previewedFilesCount = 3;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgPromote';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promotedFilesCount'.

el._promotedFilesCount = 4;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promoteDuration'.

el._promoteDuration = 3;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_previewedFilesCount'.

el._previewedFilesCount = 4;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_previewDuration'.

el._previewDuration = 2;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgDelete';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_unpublishFilesCount'.

el._unpublishFilesCount = 2;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_unpublishDuration'.

el._unpublishDuration = 1;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_deletedFilesCount'.

el._deletedFilesCount = 2;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_deleteDuration'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_org'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_sourceRepo'.

el._sourceRepo = 'myrepo';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedColor'.

el._selectedColor = 'pink';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_floodgateConfig'.

el._floodgateConfig = { some: 'config' };


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_copiedFilesCount'.

el._copiedFilesCount = 5;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_startCopy'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_done'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_resetWorkflowState'.

el._resetWorkflowState();


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_copiedFilesCount'.

expect(el._copiedFilesCount).to.equal(0);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_startCopy'.

expect(el._startCopy).to.be.false;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_done'.

expect(el._done).to.be.false;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_filesToProcess'.

expect(el._filesToProcess).to.deep.equal([]);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_org'.

expect(el._org).to.equal('myorg');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_sourceRepo'.

expect(el._sourceRepo).to.equal('myrepo');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedColor'.

expect(el._selectedColor).to.equal('pink');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_org'.


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_sourceRepo'.

el._sourceRepo = 'myrepo';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedColor'.

el._selectedColor = 'pink';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_configContextKey'.

el._configContextKey = 'myorg|myrepo';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_org'.

expect(el._org).to.equal('');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_sourceRepo'.

expect(el._sourceRepo).to.equal('');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedColor'.

expect(el._selectedColor).to.equal('');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_configContextKey'.

expect(el._configContextKey).to.equal('');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_previewAfterCopy'.

expect(el._previewAfterCopy).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_previewAfterCopy'.

expect(el._previewAfterCopy).to.be.false;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_publishAfterPromote'.

expect(el._publishAfterPromote).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_promoteIgnore'.

expect(el._promoteIgnore).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedColor'.

el._selectedColor = 'pink';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgCopy';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgPromote';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_selectedOption'.

el._selectedOption = 'fgDelete';


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_org'.

expect(el._org).to.equal('myorg');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_sourceRepo'.

expect(el._sourceRepo).to.equal('myrepo');


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_pathCount'.

expect(el._pathCount).to.equal(2);


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_canStart'.

expect(el._canStart).to.be.true;


🚫 [eslint] <no-underscore-dangle> reported by reviewdog 🐶
Unexpected dangling '_' in '_canStart'.

expect(el._canStart).to.be.false;


🚫 [eslint] <import/no-unresolved> reported by reviewdog 🐶
Unable to resolve path to module 'https://da.live/deps/lit/dist/index.js'.

import { html, nothing } from 'https://da.live/deps/lit/dist/index.js';


🚫 [eslint] <no-use-before-define> reported by reviewdog 🐶
'validatePathsExist' was used before it was defined.

cmp._notFoundPaths = await validatePathsExist(cmp, regularPaths, org, repo, operation);


🚫 [eslint] <no-use-before-define> reported by reviewdog 🐶
'findFragments' was used before it was defined.

await findFragments(cmp, org, repo, operation);


🚫 [eslint] <max-len> reported by reviewdog 🐶
This line has a length of 106. Maximum allowed is 100.

cmp._previewErrorList.push({ href: status.aemUrl, status: status.statusCode, path: status.path });


🚫 [eslint] <max-len> reported by reviewdog 🐶
This line has a length of 106. Maximum allowed is 100.

cmp._publishErrorList.push({ href: status.aemUrl, status: status.statusCode, path: status.path });

@github-actions
Copy link
Copy Markdown
Contributor

Reminder to set the Ready for Stage label - to queue this to get merged to stage & production.

@github-actions
Copy link
Copy Markdown
Contributor

This pull request is not passing all required checks. Please see this discussion for information on how to get all checks passing. Inconsistent checks can be manually retried. If a test absolutely can not pass for a good reason, please add a comment with an explanation to the PR.

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