Add deployment summary to the job summary and pull request comment - #279
Add deployment summary to the job summary and pull request comment#279chhateauuu wants to merge 12 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds post-deployment reporting to sql-action by capturing SqlPackage’s deployment report/script, converting them into a concise Markdown summary, and publishing that summary to the GitHub Actions job summary and (optionally) a sticky pull request comment.
Changes:
- Capture SqlPackage deployment report XML and deployment script during
publish, and return their paths from the action execution. - Parse the deployment report and render a Markdown “deployment summary” including change breakdowns, data-loss warnings, and an embedded script section.
- Add a reporter that writes the job summary, upserts a sticky PR comment, and sets new outputs describing changes and artifact paths.
Reviewed changes
Copilot reviewed 15 out of 17 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Reporter.ts | Implements summary publishing (job summary + sticky PR comment) and sets new outputs. |
| src/main.ts | Measures deploy duration and invokes the reporter; enables deployment report capture in inputs. |
| src/DeploymentSummary.ts | Renders GitHub-flavored Markdown summary (headline, metadata, changes, alerts, script). |
| src/DeploymentReport.ts | Parses SqlPackage deployment report XML into operations and alerts. |
| src/AzureSqlAction.ts | Adds optional capture of deployment report/script paths for publish executions. |
| README.md | Documents new inputs/outputs and deployment summary behavior. |
| package.json | Adds dependencies for GitHub API usage and XML parsing. |
| package-lock.json | Locks the dependency graph for newly added packages. |
| lib/main.js.LICENSE.txt | Updates bundled-license notices due to added dependencies. |
| action.yml | Adds new inputs/outputs and continues to point to the bundled JS entrypoint. |
| tests/Reporter.test.ts | Adds tests for summary publishing and sticky comment upsert behavior. |
| tests/main.test.ts | Updates mocks to reflect execute() now returning an action result object. |
| tests/DeploymentSummary.test.ts | Adds tests for Markdown rendering, grouping, truncation, and escaping. |
| tests/DeploymentReport.test.ts | Adds tests for report XML parsing and malformed/edge inputs. |
| tests/AzureSqlAction.test.ts | Adds tests verifying capture arg injection and path reuse behavior. |
| testdata/deployReport.xml | Adds a representative deployment report fixture for parser tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -0,0 +1,3 @@ | |||
| /*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */ | |||
There was a problem hiding this comment.
It is auto-generated by webpack's license-extraction step. Adding @actions/github pulls in node-fetch, which includes formdata-polyfill, and webpack collects those MIT notices into the main.js.LICENSE.txt sidecar next to the bundle. It is just third-party license attribution for the newly bundled dependency and is the standard output. Happy to change the bundling if you would prefer it not be emitted.
|
@chhateauuu can you go through the copilot suggestions, determine which are valid, and either address or close them all? |
| try { | ||
| parsed = parser.parse(xml); | ||
| } catch { | ||
| return { operations: [], alerts: [] }; |
There was a problem hiding this comment.
What's the behavior if parsing fails? Does it create a status comment saying it failed, or do we swallow failures?
There was a problem hiding this comment.
We swallow it by design. Reporting is best-effort and must never fail a deployment: if the report XML is missing, blank, or malformed, the parser returns an empty result, the summary omits the changes section, and the deploy is unaffected. Problems are logged via core.debug/core.warning, and the whole reporter is wrapped so an error there cannot fail the run. It does not post a "failed" status comment. If you would like a visible "deployment report could not be parsed" note in the summary for transparency, that is an easy follow-up.
Copilot suggestions: - _getBooleanInput returns the default for empty or unrecognized values - _setOutputs only sets change outputs when a report was captured - gate deployment-report capture on reporting being enabled - paginate the sticky-comment lookup so it is found past 100 comments - redact secret-looking arguments from the summary - pin @actions/github to 6.0.0 - remove the unused EMPTY_REPORT constant Reviewer notes: - friendlyType uses startsWith instead of a regex - Dropped icon changed to a cross mark - use string methods (replaceAll, trimEnd, startsWith) where a regex was not needed Add es2019/es2021 string libs, update tests, and rebuild the bundle.
| * Publishes the action outputs describing the deployment. | ||
| */ | ||
| private static _setOutputs(context: SummaryContext, result: IActionResult): void { | ||
| if (context.report) { |
There was a problem hiding this comment.
Should we still set these two when there's no report?
For .sql deployments IIRC there's no report, so these outputs never get set and anyone checking changes-detected == 'false' in their workflow gets an empty string back, their step just silently doesn't run.
action.yml says it's always 'true' or 'false', and it used to be. Maybe const operations = context.report?.operations ?? [] and set them unconditionally?
There was a problem hiding this comment.
Good call, you're right. Reverted to setting them unconditionally with const operations = context.report?.operations ?? [], so .sql and other no-report runs return false/0 instead of an empty string and the documented output contract holds. Thanks for catching that.
Per code-owner review: set changes-detected and objects-changed unconditionally (false/0 when no report is captured) so .sql and other no-report runs return 'false' instead of an empty string, matching the action.yml output contract.
Summary
When
sql-actiondeploys a database, the details of what actually changed are only visible in the build logs. A reviewer sees a green check and has to open the run and read the logs to learn what happened to the database.This PR makes the action publish a concise deployment summary of what the deployment changed. It is written to the GitHub Actions job summary and, on pull requests, posted as a single auto-updating sticky comment. It reports the objects created, altered, and dropped, warns about possible data loss, and includes the full deployment T-SQL in a collapsible section.
The information already exists: SqlPackage computes the change set during every publish. This PR captures the deployment report and script it produces, parses them, formats a summary, and publishes it. No deployment logic is added or changed.
code-walkthrough.md
What it looks like
On a pull request that changes the schema, the action posts a summary like this:
What changed
src/DeploymentReport.ts: parses the SqlPackage deployment report XML into operations and alerts. Tolerant of missing or malformed input.src/DeploymentSummary.ts: a pure function that renders the summary Markdown.src/Reporter.ts: writes the job summary, posts or updates the sticky PR comment, and sets outputs. Best-effort; it can never fail a deployment.src/AzureSqlAction.ts: during a Publish, captures the deployment report and script (respecting any caller-supplied paths) and returns their locations.src/main.ts: measures the deploy duration and invokes the reporter after a successful deploy.action.ymlandREADME.md: document the new inputs and outputs.The change is organized into small, logical commits so it can be reviewed step by step.
New inputs (all optional)
summarytruecomment-prautooff,auto,always.github-token${{ github.token }}New outputs
changes-detected,objects-changed,deployment-report-path,deployment-script-path.Behavior and safety
pull-requests: write. When the token or permission is missing, the action logs a warning and falls back to the job summary.Compatibility notes
fast-xml-parser(report parsing) and@actions/github(comment posting).@actions/githubis pinned to the v6 CommonJS line for compatibility with the existing webpack build.lib/main.jsgrows from about 284 KB to 860 KB, driven mainly by the GitHub API client.comment-prdefaults toauto. If a more conservative default is preferred, it can default tooff(opt-in). This is a one-line change; happy to adjust.Testing
npm run buildsucceeds and the committed bundle is up to date.