Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
be3b181
Remove changelog update step from emitter skill
dargilco Jun 2, 2026
88c333c
restore tsp-location.yaml
dargilco Jun 2, 2026
5fce783
[azure-ai-projects] Emit SDK from TypeSpec (commit 6aa89cf) (#47294)
dargilco Jun 2, 2026
04139a9
[azure-ai-projects] Emit SDK from TypeSpec, using latest OpenAI TypeS…
dargilco Jun 3, 2026
b3ad5b8
Cleanup unused `# [START` tages
dargilco Jun 3, 2026
2404e45
First
dargilco Jun 3, 2026
1ac2850
Separate skill for updating CHANGELOG.md file (#47327)
dargilco Jun 3, 2026
c37ce79
Update Python tsp-location.yaml to match recent TypeSpec client.tsp f…
dargilco Jun 5, 2026
9ad3073
Update subclient doc
dargilco Jun 5, 2026
7503c2f
Add sample for dispatching routines with manual triggers (#47404)
howieleung Jun 9, 2026
8c5e21f
restore packages
dargilco Jun 9, 2026
860edc3
Merge remote-tracking branch 'origin/main' into feature/azure-ai-proj…
dargilco Jun 9, 2026
29a4ea9
sample update routines (#47423)
howieleung Jun 10, 2026
7022f99
Merge remote-tracking branch 'origin/main' into feature/azure-ai-proj…
dargilco Jun 10, 2026
573d942
Merge remote-tracking branch 'origin/main' into feature/azure-ai-proj…
dargilco Jun 12, 2026
167234f
Next pylints (#47465)
weirongw23-msft Jun 12, 2026
c5e85bf
[EngSys] Lint workflows with `actionlint` (#47467)
mikeharder Jun 12, 2026
8358207
Remove unused emitter directories (#47288) (#47083)
benbp Jun 12, 2026
60cd541
Sync .github/skills directory with azure-sdk-tools for PR 15999 (#47481)
azure-sdk-automation[bot] Jun 12, 2026
5757d1c
Emit from latest TypeSpec, including new Agent Optimization methods (…
dargilco Jun 12, 2026
b5aae50
Python POC for GitHub-based API Reviews (Phase 1) (#47203)
tjprescott Jun 12, 2026
c7a9cd7
Update change log and subclient report
dargilco Jun 12, 2026
b33d8a5
Run optional post-emitter.ps1 script after SDK generation (#47456)
msyyc Jun 15, 2026
10579f9
Fix TypeSpec Python regenerate workflow: apply README template from g…
Copilot Jun 15, 2026
b0c69f4
Remove changelog update step from emitter skill
dargilco Jun 2, 2026
696c719
restore tsp-location.yaml
dargilco Jun 2, 2026
b19ddad
[azure-ai-projects] Emit SDK from TypeSpec (commit 6aa89cf) (#47294)
dargilco Jun 2, 2026
6521ec4
[azure-ai-projects] Emit SDK from TypeSpec, using latest OpenAI TypeS…
dargilco Jun 3, 2026
172b798
Cleanup unused `# [START` tages
dargilco Jun 3, 2026
907a3cf
First
dargilco Jun 3, 2026
21e4a84
Separate skill for updating CHANGELOG.md file (#47327)
dargilco Jun 3, 2026
dc50ff6
Update Python tsp-location.yaml to match recent TypeSpec client.tsp f…
dargilco Jun 5, 2026
be0e6ca
Update subclient doc
dargilco Jun 5, 2026
a39e6e0
Add sample for dispatching routines with manual triggers (#47404)
howieleung Jun 9, 2026
f0f161f
restore packages
dargilco Jun 15, 2026
c550e40
sample update routines (#47423)
howieleung Jun 10, 2026
7f2a28c
Emit from latest TypeSpec, including new Agent Optimization methods (…
dargilco Jun 12, 2026
1148869
Update change log and subclient report
dargilco Jun 12, 2026
4305e28
Merge branch 'feature/azure-ai-projects/2.3.0' of https://github.com/…
dargilco Jun 15, 2026
97d1097
restore tsp-location.yaml
dargilco Jun 2, 2026
1d78c99
[azure-ai-projects] Emit SDK from TypeSpec (commit 6aa89cf) (#47294)
dargilco Jun 2, 2026
9c44b94
[azure-ai-projects] Emit SDK from TypeSpec, using latest OpenAI TypeS…
dargilco Jun 3, 2026
a7c53a8
Update Python tsp-location.yaml to match recent TypeSpec client.tsp f…
dargilco Jun 5, 2026
587153f
Add sample for dispatching routines with manual triggers (#47404)
howieleung Jun 9, 2026
344248d
restore packages
dargilco Jun 9, 2026
324e4f6
sample update routines (#47423)
howieleung Jun 10, 2026
f8e030b
Emit from latest TypeSpec, including new Agent Optimization methods (…
dargilco Jun 12, 2026
77034cf
Merge branch 'feature/azure-ai-projects/2.3.0' of https://github.com/…
dargilco Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@
/sdk/durabletask/ @berndverst @cgillum @kaibocai @philliphoff @RyanLettieri @torosent

# PRLabel: %EngSys
/sdk/template/ @benbp @scbedd @danieljurek @weshaggard
/sdk/template/ @benbp @mikeharder @danieljurek

# PRLabel: %Evaluation
/sdk/evaluation/ @Azure/azure-sdk-write-evaluation
Expand Down Expand Up @@ -810,33 +810,33 @@
###########
# Eng Sys and other
###########
/eng/ @scbedd @danieljurek @weshaggard @benbp
/eng/ @danieljurek @mikeharder @benbp
/eng/common/ @Azure/azure-sdk-eng
/eng/tools/ @scbedd @danieljurek @mccoyp
/eng/tools/ @danieljurek @mccoyp
/.github/workflows/ @Azure/azure-sdk-eng
/.github/workflows/typespec-python-regenerate.yml @Azure/azure-sdk-eng @tadelesh @msyyc @iscai-msft @ChenxiJiang333
/.github/CODEOWNERS @lmazuel @kashifkhan @Azure/azure-sdk-eng
/.github/copilot-instructions.md @l0lawrence @praveenkuttappan @maririos
/.github/prompts/ @mccoyp @l0lawrence @benbp
/.github/skills/ @mccoyp @l0lawrence @benbp
/sdk/pullrequest.yml @scbedd @danieljurek @weshaggard @benbp
/sdk/pullrequest.yml @danieljurek @mikeharder @benbp

/.config/1espt/ @benbp @weshaggard
/.devcontainer/ @scbedd @danieljurek @mccoyp @benbp @weshaggard
/.vscode/ @scbedd @danieljurek @mccoyp @benbp @weshaggard
/.config/1espt/ @benbp @mikeharder
/.devcontainer/ @danieljurek @mccoyp @benbp @mikeharder
/.vscode/ @danieljurek @mccoyp @benbp @mikeharder

/scripts/ @scbedd @danieljurek @mccoyp
/scripts/ @danieljurek @mccoyp
/scripts/breaking_changes_checker/ @catalinaperalta
/doc/ @scbedd @danieljurek @Azure/azure-python-sdk
/conda/ @scbedd @danieljurek @lmazuel
/doc/ @danieljurek @Azure/azure-python-sdk
/conda/ @danieljurek @xiangyan99 @lmazuel

/shared_requirements.txt @azure/azure-sdk-eng @kashifkhan @xirzec

# Add owners for notifications for specific pipelines
/eng/pipelines/templates/jobs/tests-nightly-python.yml @lmazuel @mccoyp
/eng/pipelines/aggregate-reports.yml @lmazuel @mccoyp
/eng/common/pipelines/codeowners-linter.yml @lmazuel @mccoyp
/eng/pipelines/docindex.yml @danieljurek @scbedd @weshaggard @benbp
/eng/pipelines/docindex.yml @danieljurek @benbp

# Add approvers for typespec-python emitter version updates
/eng/emitter-package.json @mccoyp @catalinaperalta @iscai-msft @msyyc @ChenxiJiang333
Expand All @@ -845,8 +845,8 @@
# TypeSpec Python generated tests and regeneration workflow
/eng/tools/emitter/ @tadelesh @msyyc @iscai-msft @lmazuel @lirenhe @ChenxiJiang333

/pylintrc @l0lawrence @scbedd @danieljurek @mccoyp
/sdk/**/ci.yml @msyyc @lmazuel @scbedd @danieljurek
/pylintrc @l0lawrence @danieljurek @mccoyp
/sdk/**/ci.yml @msyyc @lmazuel @danieljurek

# Add Johnathan Walker as code owner for Event Hubs SDK
/sdk/eventhub/azure-eventhub/* @j7nw4r @SwayGom @sagar0207
Expand Down
3 changes: 3 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
self-hosted-runner:
labels:
- 1ES.Pool=azsdk-pool-github-runners
17 changes: 17 additions & 0 deletions .github/matchers/actionlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"problemMatcher": [
{
"owner": "actionlint",
"pattern": [
{
"regexp": "^(?:\\x1b\\[\\d+m)?(.+?)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*: (?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)* \\[(.+?)\\]$",
"file": 1,
"line": 2,
"column": 3,
"message": 4,
"code": 5
}
]
}
]
}
3 changes: 3 additions & 0 deletions .github/shared/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `.github/shared`

Copied from https://github.com/Azure/azure-rest-api-specs/tree/main/.github/shared
61 changes: 61 additions & 0 deletions .github/shared/src/cache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Caches values in memory with a single key of any type.
*
* @template K, V
*/
export class KeyedCache {
/** @type {Map<K, V>} */
#map = new Map();

/**
* Returns cached value, initializing if necessary
*
* @param {K} key
* @param {() => V} factory
* @returns {V} cached value
*
* @example
* const result = cache.getOrCreate(42, async () => await doWork(42));
*/
getOrCreate(key, factory) {
let value = this.#map.get(key);

if (value === undefined) {
value = factory();
this.#map.set(key, value);
}

return value;
}
}

/**
* Caches values in memory with an ordered pair of keys of any types.
*
* @template K1, K2, V
*/
export class KeyedPairCache {
// Two-layer nested cache
/** @type {KeyedCache<K1, KeyedCache<K2, V>>} */
#cache1 = new KeyedCache();

/**
* Returns cached value, initializing if necessary.
* Keys are ordered, so (key1, key2) != (key2, key1).
*
* @param {K1} key1
* @param {K2} key2
* @param {() => V} factory
* @returns {V} cached value
*
* @example
* const result = cache.getOrCreate(42, 7, async () => await doWork(42, 7));
*/
getOrCreate(key1, key2, factory) {
// key1 => cache for the next layer
const cache2 = this.#cache1.getOrCreate(key1, () => new KeyedCache());

// key2 => final value
return cache2.getOrCreate(key2, factory);
}
}
152 changes: 152 additions & 0 deletions .github/shared/src/exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import child_process from "child_process";
import { dirname, join } from "path";
import { promisify } from "util";
const execFileImpl = promisify(child_process.execFile);

/**
* @typedef {Object} ExecOptions
* @property {string} [cwd] Current working directory. Default: process.cwd().
* @property {import('./logger.js').ILogger} [logger]
* @property {boolean} [logOutput] Log captured stdout/stderr at info level. Default: false.
* @property {number} [maxBuffer] Max bytes allowed on stdout or stderr. Default: 16 * 1024 * 1024.
*/

/**
* @typedef {Object} NpmPrefixOptions
* @property {string} [prefix] Prefix to pass to npm via "--prefix".
*/

/**
* @typedef {ExecOptions & NpmPrefixOptions} ExecNpmOptions
*/

/**
* @typedef {Object} ExecResult
* @property {string} stdout
* @property {string} stderr
*/

/**
* @typedef {Error & { stdout?: string, stderr?: string, code?: number }} ExecError
*/

/**
* Checks whether an unknown error object is an ExecError.
* @param {unknown} error
* @returns {error is ExecError}
*/
export function isExecError(error) {
if (!(error instanceof Error)) return false;

const e = /** @type {ExecError} */ (error);
return typeof e.stdout === "string" || typeof e.stderr === "string";
}

/**
* Wraps `child_process.execFile()`, adding logging and a larger default maxBuffer.
*
* @param {string} file
* @param {string[]} [args]
* @param {ExecOptions} [options]
* @returns {Promise<ExecResult>}
* @throws {ExecError}
*/
export async function execFile(file, args, options = {}) {
const {
cwd,
logger,
logOutput = false,
// Node default is 1024 * 1024, which is too small for some git commands returning many entities or large file content.
// To support "git show", should be larger than the largest swagger file in the repo (2.5 MB as of 2/28/2025).
maxBuffer = 16 * 1024 * 1024,
} = options;

logger?.info(`execFile("${file}", ${JSON.stringify(args)})`);

try {
// execFile(file, args) is more secure than exec(cmd), since the latter is vulnerable to shell injection
const result = await execFileImpl(file, args, {
cwd,
maxBuffer,
});

logger?.debug(`stdout: '${result.stdout}'`);
logger?.debug(`stderr: '${result.stderr}'`);
if (logOutput) {
if (result.stdout) {
logger?.info(result.stdout.trimEnd());
}
if (result.stderr) {
logger?.info(result.stderr.trimEnd());
}
}

return result;
} catch (error) {
/* v8 ignore next */
logger?.debug(`error: '${JSON.stringify(error)}'`);
if (logOutput && isExecError(error)) {
if (error.stdout) {
logger?.info(error.stdout.trimEnd());
}
if (error.stderr) {
logger?.info(error.stderr.trimEnd());
}
}

throw error;
}
}

/**
* Calls `execFile()` with appropriate arguments to run `npm` on all platforms
*
* @param {string[]} args
* @param {ExecNpmOptions} [options]
* @returns {Promise<ExecResult>}
* @throws {ExecError}
*/
export async function execNpm(args, options = {}) {
const { prefix } = options;

// Exclude platform-specific code from coverage
/* v8 ignore start */
const { file, defaultArgs } =
process.platform === "win32"
? {
// Only way I could find to run "npm" on Windows, without using the shell (e.g. "cmd /c npm ...")
//
// "node.exe", ["--", "npm-cli.js", ...args]
//
// The "--" MUST come BEFORE "npm-cli.js", to ensure args are sent to the script unchanged.
// If the "--" comes after "npm-cli.js", the args sent to the script will be ["--", ...args],
// which is NOT equivalent, and can break if args itself contains another "--".

// example: "C:\Program Files\nodejs\node.exe"
file: process.execPath,

// example: "C:\Program Files\nodejs\node_modules\npm\bin\npm-cli.js"
defaultArgs: [
"--",
join(dirname(process.execPath), "node_modules", "npm", "bin", "npm-cli.js"),
],
}
: { file: "npm", defaultArgs: [] };
/* v8 ignore stop */

const prefixArgs = prefix ? ["--prefix", prefix] : [];

return await execFile(file, [...defaultArgs, ...prefixArgs, ...args], options);
}

/**
* Calls `execNpm()` with arguments ["exec", "--no", "--"] prepended.
*
* @param {string[]} args
* @param {ExecNpmOptions} [options]
* @returns {Promise<ExecResult>}
* @throws {ExecError}
*/
export async function execNpmExec(args, options = {}) {
return await execNpm(["exec", "--no", "--", ...args], options);
}
64 changes: 64 additions & 0 deletions .github/shared/src/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* @typedef {Object} ILogger
* @property {(message:string) => void} debug
* @property {(message:string) => void} error
* @property {(message:string) => void} info
* @property {(message:string) => void} warning
* @property {() => boolean} isDebug
*/

/**
* @implements {ILogger}
*/
export class ConsoleLogger {
/** @type {boolean} */
#isDebug;

/**
* @param {boolean} [isDebug] - If true, debug logs will be printed. Default: false.
*/
constructor(isDebug = false) {
this.#isDebug = isDebug;
}

/**
* @param {string} message
*/
debug(message) {
if (this.isDebug()) {
console.debug(message);
}
}

/**
* @param {string} message
*/
error(message) {
console.error(message);
}

/**
* @param {string} message
*/
info(message) {
console.log(message);
}

/**
* @returns {boolean}
*/
isDebug() {
return this.#isDebug;
}

/**
* @param {string} message
*/
warning(message) {
console.warn(message);
}
}

// Singleton loggers
export const defaultLogger = new ConsoleLogger();
export const debugLogger = new ConsoleLogger(/*isDebug*/ true);
Loading
Loading