-
Notifications
You must be signed in to change notification settings - Fork 358
Add azd ai dataset extension for Foundry datasets #9499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 81 commits
104cd35
7b4b19e
f5d55a2
93516a2
2e8f8fb
88ffc5f
dd0b293
5c5084b
2e7b315
9df2b57
be18334
bbc9c89
347fefb
fef40d1
5dabe21
a986da1
69e7031
8e9e3fb
897c63f
4cfa842
3a9d92f
7ceef44
454e1f3
6e7aacf
7acb239
0efc7b5
5bd8aa9
94424e0
d87b99f
aab6855
24b7c74
3faf386
289aacb
1c9ca30
35cbaec
0ff82f2
04af404
8b8b8af
048b43d
29f83f7
2a2ce2f
542fc74
98a320b
fddc3df
df07a49
bdcaa19
830bfc9
5a383e9
8ff1c88
3ca235e
3404ec8
be92ba7
ff644f6
26929aa
1e2f8e2
04522d5
0e2de78
4c8a2db
8e20270
96c2dc2
9f7b171
a823ed9
f6618d6
b87bda4
f22f8af
2cc7502
fe4a250
7208ac4
91220f8
e35d4ca
9c09ddf
99b67a3
5e46d62
f73d04a
09167a3
b2284f6
904e633
606e8c7
15e854d
1868ae3
56b6488
6236d6c
3e6cd9d
b52250a
46622e1
5b6be3d
d46f767
f8c98ed
4255a65
8e558ee
c7a997c
a6b328a
efaf6c4
77537b4
c613c86
c4ce547
66a2ce8
69291c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| name: ext-azure-ai-dataset-ci | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - "cli/azd/extensions/azure.ai.dataset/**" | ||
| - ".github/workflows/lint-ext-azure-ai-dataset.yml" | ||
| branches: [main] | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: write # required by reusable workflow lint-go.yml | ||
|
|
||
| jobs: | ||
| lint: | ||
| uses: ./.github/workflows/lint-go.yml | ||
| with: | ||
| working-directory: cli/azd/extensions/azure.ai.dataset |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Test report written by ci-test.ps1 for the pipeline to publish. | ||
| junitTestReport.xml | ||
|
|
||
| # Debug log written when --debug or AZD_EXT_DEBUG is set. | ||
| azd-ai-dataset-*.log |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| version: "2" | ||
|
|
||
| linters: | ||
| default: none | ||
| enable: | ||
| - gosec | ||
| - lll | ||
| - unused | ||
| - errorlint | ||
| settings: | ||
| lll: | ||
| line-length: 220 | ||
|
|
||
| tab-width: 4 | ||
| gosec: | ||
| excludes: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [azd-code-reviewer][severity: medium] These module-wide exclusions disable the subprocess and variable-file checks for production code, while the |
||
| - G204 # Subprocess launched with variable (bicep build invoked in tests) | ||
| - G304 # Potential file inclusion via variable | ||
|
|
||
| formatters: | ||
| enable: | ||
| - gofmt | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # Release History | ||
|
|
||
| ## 1.0.0-beta.17 (2026-08-20) | ||
|
|
||
| First release of the Foundry datasets extension. | ||
|
|
||
| ### Features Added | ||
|
|
||
| - Register and manage Foundry datasets from the terminal: `create`, `update`, | ||
| `list`, `show`, `delete`, and `versions list`. | ||
| - Publishes a local `.jsonl` file or folder as a versioned dataset, picking the | ||
| next version from what the project already carries. `--version` publishes at | ||
| exactly that version instead, on `create` and `update` alike. | ||
| - Validates before sending: a malformed row, an empty dataset, a name the | ||
| service will not take, and a folder that could mean more than one dataset are | ||
| each refused locally. | ||
| - Reads dataset content back, whether the service hands out a blob URI or the | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [azd-code-reviewer][severity: low] No registered command calls |
||
| container holding it. | ||
| - `-o json` on every command, and `--no-prompt` for unattended use. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| # Foundry datasets (Beta) | ||
|
|
||
| Register and version Foundry datasets from your terminal. | ||
|
|
||
| ```console | ||
| $ azd extension install azure.ai.dataset | ||
|
|
||
| $ azd ai dataset --help | ||
| ``` | ||
|
|
||
| A dataset is a general Foundry asset: evaluation needs one, and so do | ||
| fine-tuning and other scenarios. That is why these commands live here rather | ||
| than inside `azure.ai.evaluations`. | ||
|
|
||
| ## Commands | ||
|
|
||
| | Command | What it does | | ||
| |---|---| | ||
| | `azd ai dataset create <name> --from-file <path>` | Register a dataset, publishing its first version | | ||
| | `azd ai dataset update <name> --from-file <path>` | Publish a further version | | ||
| | `azd ai dataset list` | List the project's datasets | | ||
| | `azd ai dataset show <name>` | Show one dataset | | ||
| | `azd ai dataset delete <name>` | Delete a dataset version | | ||
| | `azd ai dataset versions list <name>` | List a dataset's versions | | ||
|
|
||
| `--version` names the version to publish, on `create` and `update` alike. Omit | ||
| it and the next version after the latest registered one is published; a version | ||
| the service already holds is refused rather than stepped past, because a version | ||
| you named is one you meant. | ||
|
|
||
| ## Generating a dataset | ||
|
|
||
| Generation is `azd ai eval generate`, in `azure.ai.evaluations`, and stays | ||
| there: it writes the `datasets:` entry in `evals/azure.eval.yaml`, which is that | ||
| extension's file. Splitting the two would leave a generated dataset registered | ||
| with the service but absent from the configuration, so `azd up` would not | ||
| reconcile it and no eval could name it. | ||
|
|
||
| Once a file exists, `create` registers it here. | ||
|
|
||
| ## Project endpoint | ||
|
|
||
| Every command resolves the Foundry project endpoint in this order: | ||
|
|
||
| 1. `--project-endpoint` | ||
| 2. `FOUNDRY_PROJECT_ENDPOINT` in the active azd environment, then | ||
| `AZURE_AI_PROJECT_ENDPOINT` there | ||
| 3. `extensions.ai-agents.project.context.endpoint` in azd's global config, | ||
| which `azure.ai.agents` writes and this extension only reads | ||
| 4. `FOUNDRY_PROJECT_ENDPOINT` in the host environment, then | ||
| `AZURE_AI_PROJECT_ENDPOINT` | ||
|
|
||
| Level 3 is worth knowing about: it is machine-wide rather than per-project, so | ||
| a project context left behind by `azd ai agent` somewhere else takes precedence | ||
| over the variable exported in this shell. `--debug` prints which level answered. | ||
|
Comment on lines
+47
to
+54
|
||
|
|
||
| ## Building | ||
|
|
||
| ```console | ||
| $ go build ./... | ||
| $ go test ./... | ||
| ``` | ||
|
|
||
| ## TODO before release | ||
|
|
||
| Both are files the azd extensions team owns, so they are not changed here: | ||
|
|
||
| - [ ] **`cli/azd/extensions/registry.json`** — add the `azure.ai.dataset` entry. | ||
| Until it exists `azd extension install azure.ai.dataset` cannot resolve, so | ||
| the extension is only reachable through `azd x pack` + `azd x publish` into | ||
| the local source registry. | ||
| - [ ] **`.github/CODEOWNERS`** — add `/cli/azd/extensions/azure.ai.dataset/`. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [azd-code-reviewer][severity: low] This PR now adds the dataset rule to |
||
| Every sibling Foundry extension has an entry; without one, PRs here get no | ||
| reviewer routing. | ||
|
m7md7sien marked this conversation as resolved.
Outdated
|
||
| - [ ] **`microsoft.foundry/extension.yaml`** — add the dependency, but only | ||
| after the registry entry lands. Declaring a dependency that cannot resolve | ||
| breaks installing the bundle. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| # Ensure script fails on any error | ||
| $ErrorActionPreference = 'Stop' | ||
|
|
||
| # Get the directory of the script | ||
| $EXTENSION_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path | ||
|
|
||
| # Change to the script directory | ||
| Set-Location -Path $EXTENSION_DIR | ||
|
|
||
| # Create a safe version of EXTENSION_ID replacing dots with dashes | ||
| $EXTENSION_ID_SAFE = $env:EXTENSION_ID -replace '\.', '-' | ||
|
|
||
| # Define output directory | ||
| $OUTPUT_DIR = if ($env:OUTPUT_DIR) { $env:OUTPUT_DIR } else { Join-Path $EXTENSION_DIR "bin" } | ||
|
|
||
| # Create output directory if it doesn't exist | ||
| if (-not (Test-Path -Path $OUTPUT_DIR)) { | ||
| New-Item -ItemType Directory -Path $OUTPUT_DIR | Out-Null | ||
| } | ||
|
|
||
| # Get Git commit hash and build date | ||
| $COMMIT = git rev-parse HEAD | ||
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Host "Error: Failed to get git commit hash" | ||
| exit 1 | ||
| } | ||
| $BUILD_DATE = ((Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) | ||
|
|
||
| # List of OS and architecture combinations | ||
| if ($env:EXTENSION_PLATFORM) { | ||
| $PLATFORMS = @($env:EXTENSION_PLATFORM) | ||
| } | ||
| else { | ||
| $PLATFORMS = @( | ||
| "windows/amd64", | ||
| "windows/arm64", | ||
| "darwin/amd64", | ||
| "darwin/arm64", | ||
| "linux/amd64", | ||
| "linux/arm64" | ||
| ) | ||
| } | ||
|
|
||
| $VERSION_PATH = "azureaidataset/internal/version" | ||
|
|
||
| # Loop through platforms and build | ||
| foreach ($PLATFORM in $PLATFORMS) { | ||
| $OS, $ARCH = $PLATFORM -split '/' | ||
|
|
||
| $OUTPUT_NAME = Join-Path $OUTPUT_DIR "$EXTENSION_ID_SAFE-$OS-$ARCH" | ||
|
|
||
| if ($OS -eq "windows") { | ||
| $OUTPUT_NAME += ".exe" | ||
| } | ||
|
|
||
| Write-Host "Building for $OS/$ARCH..." | ||
|
|
||
| # Delete the output file if it already exists | ||
| if (Test-Path -Path $OUTPUT_NAME) { | ||
| Remove-Item -Path $OUTPUT_NAME -Force | ||
| } | ||
|
|
||
| # Set environment variables for Go build | ||
| $env:GOOS = $OS | ||
| $env:GOARCH = $ARCH | ||
|
|
||
| go build ` | ||
| -ldflags="-X '$VERSION_PATH.Version=$env:EXTENSION_VERSION' -X '$VERSION_PATH.Commit=$COMMIT' -X '$VERSION_PATH.BuildDate=$BUILD_DATE'" ` | ||
| -o $OUTPUT_NAME | ||
|
|
||
| if ($LASTEXITCODE -ne 0) { | ||
| Write-Host "An error occurred while building for $OS/$ARCH" | ||
| exit 1 | ||
| } | ||
| } | ||
|
|
||
| Write-Host "Build completed successfully!" | ||
| Write-Host "Binaries are located in the $OUTPUT_DIR directory." |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| #!/bin/bash | ||
|
|
||
| # Get the directory of the script | ||
| EXTENSION_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
|
|
||
| # Change to the script directory | ||
| cd "$EXTENSION_DIR" || exit | ||
|
|
||
| # Create a safe version of EXTENSION_ID replacing dots with dashes | ||
| EXTENSION_ID_SAFE="${EXTENSION_ID//./-}" | ||
|
|
||
| # Define output directory | ||
| OUTPUT_DIR="${OUTPUT_DIR:-$EXTENSION_DIR/bin}" | ||
|
|
||
| # Create output and target directories if they don't exist | ||
| mkdir -p "$OUTPUT_DIR" | ||
|
|
||
| # Get Git commit hash and build date | ||
| COMMIT=$(git rev-parse HEAD) | ||
| BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ) | ||
|
|
||
| # List of OS and architecture combinations | ||
| if [ -n "$EXTENSION_PLATFORM" ]; then | ||
| PLATFORMS=("$EXTENSION_PLATFORM") | ||
| else | ||
| PLATFORMS=( | ||
| "windows/amd64" | ||
| "windows/arm64" | ||
| "darwin/amd64" | ||
| "darwin/arm64" | ||
| "linux/amd64" | ||
| "linux/arm64" | ||
| ) | ||
| fi | ||
|
|
||
| VERSION_PATH="azureaidataset/internal/version" | ||
|
|
||
| # Loop through platforms and build | ||
| for PLATFORM in "${PLATFORMS[@]}"; do | ||
| OS=$(echo "$PLATFORM" | cut -d'/' -f1) | ||
| ARCH=$(echo "$PLATFORM" | cut -d'/' -f2) | ||
|
|
||
| OUTPUT_NAME="$OUTPUT_DIR/$EXTENSION_ID_SAFE-$OS-$ARCH" | ||
|
|
||
| if [ "$OS" = "windows" ]; then | ||
| OUTPUT_NAME+='.exe' | ||
| fi | ||
|
|
||
| echo "Building for $OS/$ARCH..." | ||
|
|
||
| # Delete the output file if it already exists | ||
| [ -f "$OUTPUT_NAME" ] && rm -f "$OUTPUT_NAME" | ||
|
|
||
| # Set environment variables for Go build | ||
| GOOS=$OS GOARCH=$ARCH go build \ | ||
| -ldflags="-X '$VERSION_PATH.Version=$EXTENSION_VERSION' -X '$VERSION_PATH.Commit=$COMMIT' -X '$VERSION_PATH.BuildDate=$BUILD_DATE'" \ | ||
| -o "$OUTPUT_NAME" | ||
|
|
||
| if [ $? -ne 0 ]; then | ||
| echo "An error occurred while building for $OS/$ARCH" | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| echo "Build completed successfully!" | ||
| echo "Binaries are located in the $OUTPUT_DIR directory." |
Uh oh!
There was an error while loading. Please reload this page.