Skip to content

Sync eng/common directory with azure-sdk-tools for PR 15278#9895

Open
azure-sdk wants to merge 3 commits intomainfrom
sync-eng/common-add-playground-bundle-template-15278
Open

Sync eng/common directory with azure-sdk-tools for PR 15278#9895
azure-sdk wants to merge 3 commits intomainfrom
sync-eng/common-add-playground-bundle-template-15278

Conversation

@azure-sdk
Copy link
Copy Markdown
Collaborator

Sync eng/common directory with azure-sdk-tools for PR Azure/azure-sdk-tools#15278 See eng/common workflow

JoshLove-msft and others added 3 commits April 24, 2026 00:47
Adds an opt-in capability to the shared TypeSpec emitter pipeline template that bundles an emitter package and uploads it to the typespec playground blob storage. The uploaded <pkgName>/latest.json import map is consumed by in-browser playgrounds (e.g. https://azure.github.io/typespec-azure) via their additionalPlaygroundPackages mechanism.

Self-contained tooling lives in eng/common/playground-bundle/ and mirrors @typespec/bundle-uploader from microsoft/typespec (which is private and cannot be installed from npm).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@azure-sdk azure-sdk requested a review from a team as a code owner April 24, 2026 00:54
@azure-sdk azure-sdk added EngSys This issue is impacting the engineering system. Central-EngSys This issue is owned by the Engineering System team. labels Apr 24, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a self-contained Node-based uploader under eng/common to bundle TypeSpec emitter packages and publish them to the TypeSpec playground storage, plus an opt-in pipeline hook to run it from the shared TypeSpec emitter archetype.

Changes:

  • Added eng/common/playground-bundle/upload.mjs to bundle an emitter package via @typespec/bundler and upload bundle assets + manifests to typespec storage.
  • Added a pinned-dependency Node package (package.json + package-lock.json) and documentation for the uploader tool.
  • Extended archetype-typespec-emitter.yml with a new UploadPlaygroundBundle parameter and an internal non-PR upload step using AzureCLI@2.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
eng/common/playground-bundle/upload.mjs Implements bundling + blob upload workflow for TypeSpec playground consumption.
eng/common/playground-bundle/package.json Declares pinned runtime dependencies and Node engine requirement for the uploader.
eng/common/playground-bundle/package-lock.json Locks dependency graph for reproducible installs in pipelines.
eng/common/playground-bundle/README.md Documents purpose and pipeline invocation of the uploader.
eng/common/pipelines/templates/archetype-typespec-emitter.yml Adds opt-in pipeline steps to install and run the uploader on internal non-PR builds.
Files not reviewed (1)
  • eng/common/playground-bundle/package-lock.json: Language not supported

Comment on lines +133 to +142
const manifestExisted = await manifestAlreadyExists(container, bundle.manifest);
if (!manifestExisted) {
for (const file of bundle.files) {
await uploadJsFile(container, bundle.manifest.name, resolvedVersion, file);
}
await uploadManifest(container, bundle.manifest);
console.log(`✔ Uploaded bundle ${bundle.manifest.name}@${resolvedVersion}`);
} else {
console.log(`Bundle ${bundle.manifest.name}@${resolvedVersion} already exists, skipping upload.`);
}
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

The existence check + conditional upload has a TOCTOU race: another pipeline/job can upload the manifest between manifestAlreadyExists and uploadManifest, causing uploadManifest to fail on ifNoneMatch: "*" and fail the job even though the desired state is reached. Consider catching the specific Storage error (e.g., condition-not-met / 412) and treating it as "already exists" (skip) to make retries/concurrent runs fully idempotent.

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +73
const content = JSON.stringify(manifest);
await blob.upload(content, content.length, {
blobHTTPHeaders: { blobContentType: "application/json; charset=utf-8" },
conditions: { ifNoneMatch: "*" },
});
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

blob.upload(content, content.length, ...) uses JavaScript string length (UTF-16 code units), which can differ from the actual byte size sent over the wire. This can cause Azure Storage to reject the upload or truncate when the JSON contains non-ASCII characters. Use Buffer.byteLength(content, 'utf8') (or upload via uploadData(Buffer.from(content))) to provide the correct length.

Copilot uses AI. Check for mistakes.
Comment on lines +89 to +93
const blob = container.getBlockBlobClient(normalizePath(joinUnix(pkgName, "latest.json")));
const content = JSON.stringify(index);
await blob.upload(content, content.length, {
blobHTTPHeaders: { blobContentType: "application/json; charset=utf-8" },
});
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

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

Same string-length vs byte-length issue as above: blob.upload(content, content.length, ...) should use the UTF-8 byte length (e.g., Buffer.byteLength) or upload a Buffer. Otherwise latest.json uploads can fail or be corrupted for non-ASCII content.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Central-EngSys This issue is owned by the Engineering System team. EngSys This issue is impacting the engineering system.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants