Enable extension CI builds — daily + PR#7497
Conversation
baccf05 to
3929c5d
Compare
There was a problem hiding this comment.
Pull request overview
Adds an internal CI path for producing “rolling” unsigned extension builds from main, publishing them to stable *-dev GitHub release tags, and providing a dev registry JSON that points azd’s extension installer at those artifacts.
Changes:
- Adds a
publish-extension-dev.ymlstage that packages CI-built extension binaries and publishes them to a{SanitizedExtensionId}-devGitHub prerelease. - Wires the dev publish stage into the extension release pipeline template for internal CI runs (
IndividualCI/BatchedCI). - Introduces
cli/azd/extensions/registry-dev.jsonas a static registry pointing at the dev release download URLs.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| eng/pipelines/templates/stages/release-azd-extension.yml | Conditionally includes the new dev publish stage for internal CI builds. |
| eng/pipelines/templates/stages/publish-extension-dev.yml | New stage to delete/recreate a *-dev GitHub prerelease and upload packaged artifacts. |
| cli/azd/extensions/registry-dev.json | New dev registry pointing to *-dev release artifacts for 8 extensions. |
3929c5d to
dbc0e49
Compare
dbc0e49 to
5be88af
Compare
8e87775 to
2d132f5
Compare
Addressed review comments. Requesting re-review.
jongio
left a comment
There was a problem hiding this comment.
Solid PR - per-extension registry entries cleanly avoid the concurrent blob mutation problem. Version stamping is consistent across all build and cross-build jobs now, and the pipeline flow (BuildAndTest -> Sign -> PublishDaily) checks out.
One observation:
- eng/pipelines/templates/steps/publish-extension.yml:15 - parameter defaults create a silent skip trap for future callers (see inline)
Previous feedback from jongio and hemarina looks addressed.
wbreza
left a comment
There was a problem hiding this comment.
Code Review — PR #7497
Enable dev extension builds on CI by @rajeshkamal5050
Summary
Great addition to the extension dev workflow! The per-extension daily registry pattern is a clean solution that avoids the concurrent blob mutation problem entirely. The overall architecture — version stamping → build → sign → publish → registry — mirrors the established core CLI daily build pattern well.
Previous feedback from @jongio, @hemarina, and @vhvb1989 has been largely addressed. Two new findings below, plus a few maintenance items.
Prior Review Regression Check
| # | Prior Finding | Author | Status |
|---|---|---|---|
| 1 | Version override missing from build/cross-build jobs | @jongio | ✅ Resolved |
| 2 | azcopy failure silently wipes registry | @jongio | ✅ Resolved |
| 3 | Concurrent race on shared blob | @jongio | ✅ Resolved |
| 4 | _manifest removal conditional gap | @hemarina | ✅ Resolved |
| 5 | Missing usage validation | @hemarina | ✅ Resolved |
| 6 | Regex YAML parsing fragility | @jongio | ⏳ Open |
| 7 | CreateGitHubRelease defaults trap | @jongio | ⏳ Open |
Findings Summary
| Priority | Count |
|---|---|
| High | 2 |
| Medium | 3 |
| Low | 1 |
| Total | 6 |
✅ What Looks Good
- Per-extension registry entries elegantly eliminate the concurrent blob race condition
- SHA256 checksums from signed artifacts ensure supply chain integrity
- Version stamping mirrors the core CLI daily build pattern correctly
- JSON validated locally before upload;
Continue = 'Stop'prevents silent failures - Clean stage separation: build → sign → publish
This is a great improvement to the extension dev workflow — having daily builds available mirrors what the core CLI already offers and will significantly improve the inner loop for extension development and testing.
Overall Assessment: Comment — High findings warrant discussion, but the core pattern is solid and well-designed.
Review performed with GitHub Copilot CLI
eng/pipelines/templates/steps/update-extension-daily-registry.yml
Outdated
Show resolved
Hide resolved
danieljurek
left a comment
There was a problem hiding this comment.
We'll need to test this e2e to make sure it works before merging it.
jongio
left a comment
There was a problem hiding this comment.
Issues to address:
- cli/azd/extensions/azure.ai.agents/extension.yaml - version field still says 0.1.20-preview but version.txt was bumped to 0.1.21-preview. All other extensions were synced in both files.
- eng/scripts/Update-ExtensionDailyRegistry.ps1:155 - raw string replacement of ${USAGE} into the JSON template doesn't JSON-escape the value. Current extension.yaml files are fine, but if any usage field ever contains a double-quote or backslash, the generated JSON breaks silently. ConvertFrom-Json catches it downstream, but the error won't point at the cause.
Per-extension registry approach is solid - cleanly avoids the concurrent blob mutation problem.
wbreza
left a comment
There was a problem hiding this comment.
Code Re-Review — PR #7497
Enable dev extension builds on CI by @rajeshkamal5050
Re-review after force-push
Changes since my Apr 7 review (b3e211d) are in commit fe4304a:
- Regex → powershell-yaml for proper YAML parsing (addresses my prior finding)
- Registry format wrapped in
{ extensions: [...] }for azd compatibility - CreateGitHubRelease default flipped to false (safe default)
- Idempotency guard for version script pipeline retries
- Null checks + file-exists guards throughout
- Template moved to eng/templates/ with split copy steps
Prior Review: All ✅ Resolved
| # | Priority | Finding | Status |
|---|---|---|---|
| 1 | High | Regex YAML parsing fragility | ✅ Replaced with powershell-yaml |
| 2 | High | Per-extension registry entries (race condition fix) | ✅ Already resolved |
| 3 | Medium | Version override in build/cross-build jobs | ✅ Resolved |
| 4 | Medium | _manifest removal | ✅ Unconditional |
| 5 | Low | Usage validation | ✅ Added |
✅ What Looks Good
- powershell-yaml replaces fragile regex parsing — proper YAML handling
- Per-extension registry entries elegantly eliminate concurrent blob mutation
- SHA256 checksums from signed artifacts ensure supply chain integrity
- Safe defaults: CreateGitHubRelease=false, explicit true in release caller
- Idempotency guard prevents duplicate version suffixes on retries
- Daily publish stage correctly scoped to CI builds (IndividualCI/BatchedCI) — PR builds skip it
Overall Assessment: Re-approve — all findings addressed, no new issues. Pending @danieljurek's E2E validation.
Review performed with GitHub Copilot CLI
Mirrors the core CLI daily build pattern. On CI builds (push to main),
sign and upload extension binaries to Azure Storage.
- publish-extension-daily.yml — new stage, depends on Sign, uploads to
{ext-id}/daily (latest) and {ext-id}/daily/archive/{version} (history)
- publish-extension.yml — add CreateGitHubRelease param (default true)
so daily can skip GitHub Release and just upload to storage
- release-azd-extension.yml — wire daily publish for CI builds
- update-daily-registry.yml — download existing registry-daily.json from
storage, merge in the current extension entry with checksums and
storage URLs, upload back. Self-maintaining across extension builds.
Closes #7317
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pipeline changes:
- publish-extension-daily.yml — daily stage, depends on Sign, uploads
to {ext-id}/daily and {ext-id}/daily/archive/{version}
- publish-extension.yml — add CreateGitHubRelease param so daily can
skip GitHub Release and just upload to storage
- release-azd-extension.yml — wire daily publish for CI builds
- update-extension-daily-registry.yml — calls Update-ExtensionDailyRegistry.ps1
to merge extension entry into registry-daily.json on storage
- extension-registry-daily-template.json — JSON template with placeholders
Version bumps:
- Bump all extension version.txt and extension.yaml so daily builds
are ahead of the last released versions
Closes #7317
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mirrors core CLI pattern: appends -daily.<BuildId> for CI builds, -pr.<BuildId> for PR builds, skips for Manual (release) builds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Trim version.txt on read (Set-ExtensionVersionVariable, Set-ExtensionVersionInBuild) - Validate empty version.txt in Set-ExtensionVersionInBuild - Make BuildReason/BuildId mandatory params - Wrap Get-FileHash in try/catch - Validate required YAML fields (namespace, displayName, description) after parsing - Log parsed extension metadata for pipeline diagnostics - Fix upload error handling (don't set ErrorActionPreference=Continue before upload) - Guard CreateGitHubRelease against empty TagPrefix/TagVersion Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… fix, usage validation
- Add set-extension-version-cd.yml to build and cross-build jobs so
binaries get the daily version suffix (not just release artifacts)
- Switch from shared registry-daily.json to per-extension entries
(daily-registry-entries/{id}.json) to avoid race condition when
multiple extension pipelines run concurrently
- Make _manifest removal unconditional before conditional blocks
- Add usage to required fields validation in registry script
- Document YAML regex parsing limitation in code comment
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…andling
- Replace regex YAML parsing with powershell-yaml for proper parsing
- Wrap JSON output in { extensions: [...] } registry format for azd compatibility
- Move template to eng/templates/, copy scripts into release-metadata artifact
- Flip CreateGitHubRelease default to false, explicit true in release caller
- Add idempotency guard in version script for pipeline retries
- Add placeholder validation, null checks, and file-exists guards
- Split copy steps for clearer error attribution in CI
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add publish-extension-pr.yml stage for PR builds - Add update-extension-pr-registry.yml step for per-extension PR registry - Wire PR publish into release-azd-extension.yml pipeline - Add PR number validation guard for empty/unexpanded values - Add unsigned binary warning to PR comment - Add ConvertTo-JsonSafeString for JSON-safe template replacements - Bump azure.ai.agents version to 0.1.22-preview Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
86a6faa to
49986ec
Compare
|
@danieljurek all 9 extension pipelines should be on the internal ADO project right? currently only azure.ai.models and azure.appservice are internal, the rest run on public and skip sign + publish stages. these did not get PublishForPR:
|
azd Extension Install Instructions —
|
| Platform | Download |
|---|---|
| Linux x86_64 | https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/azure-appservice/pr/7497/azure-appservice-linux-amd64.tar.gz |
| Linux ARM64 | https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/azure-appservice/pr/7497/azure-appservice-linux-arm64.tar.gz |
| macOS x86_64 | https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/azure-appservice/pr/7497/azure-appservice-darwin-amd64.zip |
| macOS ARM64 | https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/azure-appservice/pr/7497/azure-appservice-darwin-arm64.zip |
| Windows x86_64 | https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/azure-appservice/pr/7497/azure-appservice-windows-amd64.zip |
| Windows ARM64 | https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/azure-appservice/pr/7497/azure-appservice-windows-arm64.zip |
jongio
left a comment
There was a problem hiding this comment.
3 TODO debug shortcuts need to be reverted before merge - they disable cross-compile validation for all extensions and skip tests for the demo extension.
| # TODO: Revert this before merge | ||
| # ValidateCrossCompile: ${{ build.value.ValidateCrossCompile }} | ||
| # TODO: Remove this line before merge | ||
| ValidateCrossCompile: false |
There was a problem hiding this comment.
These 3 TODO items (SkipTests: true in the demo pipeline, and the ValidateCrossCompile override here) need to be reverted before merge - they disable cross-compile validation for all extensions and skip tests for the demo extension.
What
Daily and PR extension builds to Azure Storage, mirrors core CLI build pattern.
On CI push to main — extensions get signed and uploaded to storage with per-extension registry entries.
On PR builds — same thing but scoped to the PR number, with install instructions posted as a PR comment.
Changes
publish-extension-daily.yml— daily publish stage, depends on Sign, uploads to storagepublish-extension-pr.yml— PR publish stage, uploads to PR-scoped storage, posts install commentpublish-extension.yml—CreateGitHubReleaseparam so daily/PR can skip itrelease-azd-extension.yml— wired daily + PR publish for CI and PR buildsSet-ExtensionVersionInBuild.ps1— appends-daily.or-pr.suffix per build reasonUpdate-ExtensionDailyRegistry.ps1+ JSON template — generates per-extension registry entries with checksumsupdate-extension-pr-registry.yml— uploads PR-scoped registry entryPer-extension registry
Each extension uploads its own entry. No shared blob, no race condition when multiple extensions build concurrently.
How to use — daily builds
Daily registry entries at:
Install a daily build:
How to use — PR builds
PR builds post a comment on the PR with install instructions. Registry entries at:
Install a PR build:
Closes #7317