From e0b7fe8cb18a28dbf30a083ed62ede28ef01608e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 18:26:19 +0000 Subject: [PATCH 01/13] Initial plan From 3f7b9d46cb1cd911e7c84b3474846be26f6a18b1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 18:31:14 +0000 Subject: [PATCH 02/13] docs: add high-level architecture diagram in Mermaid Closes #26 Agent-Logs-Url: https://github.com/Azure/apiops-cli/sessions/15f271f0-72f4-4cb9-9bb7-e2388e18c352 Co-authored-by: EMaher <9244742+EMaher@users.noreply.github.com> --- README.md | 1 + docs/architecture.md | 163 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 docs/architecture.md diff --git a/README.md b/README.md index 892cb05d..d949a869 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ |---|---| | **Source code** | [github.com/Azure/apiops-cli](https://github.com/Azure/apiops-cli) | | **Issues** | [GitHub Issues](https://github.com/Azure/apiops-cli/issues) | +| **Architecture** | [docs/architecture.md](./docs/architecture.md) | ## Getting started diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 00000000..910ed15e --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,163 @@ +# Architecture + +## Overview + +`apiops` implements a **configuration-as-code** workflow for Azure API Management (APIM). Configuration is extracted from a running APIM instance into version-controlled artifact files. Those files become the source of truth for publishing to one or more environments, driven by a CI/CD pipeline. + +--- + +## Configuration-as-Code Workflow + +The diagram below shows how `apiops` fits into a typical team workflow: + +```mermaid +flowchart LR + dev(["๐Ÿ‘ค Developer"]) + + subgraph repo["Git Repository"] + artifacts["๐Ÿ“ APIM Artifacts\n(JSON + XML)"] + ci["โš™๏ธ CI/CD Workflows\n(GitHub Actions /\nAzure DevOps)"] + end + + subgraph azure["Azure"] + apim_src["๐Ÿ”ต Source APIM\n(e.g. Dev)"] + apim_stg["๐ŸŸก APIM\n(Staging)"] + apim_prd["๐Ÿ”ด APIM\n(Production)"] + end + + dev -- "apiops extract" --> artifacts + dev -- "apiops init" --> ci + apim_src -. "reads config" .-> artifacts + ci -- "apiops publish" --> apim_stg + ci -- "apiops publish\n(with overrides)" --> apim_prd +``` + +| Step | Command | Description | +|------|---------|-------------| +| 1 | `apiops init` | Scaffolds the Git repository with CI/CD workflow files and an identity setup guide | +| 2 | `apiops extract` | Reads the running APIM configuration and writes it to local artifact files | +| 3 | `apiops publish` | Reads artifact files and creates/updates/deletes resources in the target APIM | + +--- + +## Component Architecture + +The diagram below shows the internal structure of the `apiops` CLI: + +```mermaid +flowchart TB + subgraph entrypoint["CLI Entry Point"] + extract_cmd["extract"] + publish_cmd["publish"] + init_cmd["init"] + end + + subgraph auth["Authentication (@azure/identity)"] + dac["DefaultAzureCredential\nOIDC ยท Service Principal\nManaged Identity ยท Azure CLI"] + end + + subgraph services["Services"] + direction TB + extract_svc["Extract Service\n(parallel by dependency tier)"] + filter_svc["Filter + Transitive Resolver"] + + publish_svc["Publish Service\n(dependency-ordered PUT / DELETE)"] + override_svc["Override Merger\n(per-environment config)"] + git_svc["Git Diff Service\n(incremental publish)"] + dry_svc["Dry-run Reporter"] + + init_svc["Init Service\n(CI/CD scaffolding)"] + end + + subgraph clients["Clients"] + apim_client["APIM REST Client\n(Azure Management API)"] + store["Artifact Store\n(Local Filesystem)"] + end + + subgraph external["External Systems"] + azure_apim[("Azure APIM")] + local_files[("Artifact Files\nJSON ยท XML ยท YAML")] + git_repo[("Git Repository")] + cicd_files[("CI/CD Workflow Files")] + end + + extract_cmd --> extract_svc + publish_cmd --> publish_svc + init_cmd --> init_svc + + extract_svc --> filter_svc + extract_svc --> apim_client + extract_svc --> store + + publish_svc --> override_svc + publish_svc --> git_svc + publish_svc --> dry_svc + publish_svc --> apim_client + publish_svc --> store + + apim_client --> auth + auth --> azure_apim + store <--> local_files + git_svc --> git_repo + init_svc --> cicd_files +``` + +### Extract flow + +`apiops extract` fetches every resource type from the APIM Management API and writes each resource to a corresponding artifact file on disk. Extraction is parallelized across independent resource types and can be narrowed with a filter file; transitive dependencies (e.g. backends referenced by a policy) are automatically included. + +### Publish flow + +`apiops publish` reads artifact files from disk and applies them to the target APIM instance in topological dependency order (backends before APIs, APIs before products, etc.). Three optional modes reduce blast radius: + +- **`--dry-run`** โ€” prints the plan without making any changes +- **`--overrides `** โ€” merges per-environment values (backend URLs, named-value secrets) before publishing +- **`--commit-id `** โ€” incremental mode; only resources whose artifact files changed in that Git commit are published + +### Init flow + +`apiops init` scaffolds the repository with ready-to-use GitHub Actions or Azure DevOps workflow files and generates an `identity-setup.prompt.md` guide for configuring OIDC federated credentials โ€” no client secrets required. + +--- + +## Authentication + +`apiops` uses [`DefaultAzureCredential`](https://learn.microsoft.com/azure/developer/javascript/sdk/authentication/overview) from the `@azure/identity` SDK. Credentials are tried in this order: + +| Credential | Typical use | +|---|---| +| Workload Identity (OIDC) | GitHub Actions / Azure Pipelines | +| Service Principal (env vars or flags) | Legacy CI/CD, scripts | +| Managed Identity | Azure-hosted runners, VMs, App Service | +| Azure CLI / Azure Developer CLI | Local development | + +No secrets are required when running in GitHub Actions workflows generated by `apiops init` โ€” authentication is handled entirely via OIDC federated credentials. + +--- + +## Artifact File Layout + +``` +apim-artifacts/ +โ”œโ”€โ”€ apis/ +โ”‚ โ””โ”€โ”€ orders-api/ +โ”‚ โ”œโ”€โ”€ apiInformation.json +โ”‚ โ”œโ”€โ”€ policy.xml +โ”‚ โ””โ”€โ”€ operations/ +โ”‚ โ””โ”€โ”€ get-order/ +โ”‚ โ””โ”€โ”€ policy.xml +โ”œโ”€โ”€ backends/ +โ”‚ โ””โ”€โ”€ orders-backend/ +โ”‚ โ””โ”€โ”€ backendInformation.json +โ”œโ”€โ”€ named values/ +โ”‚ โ””โ”€โ”€ orders-url/ +โ”‚ โ””โ”€โ”€ namedValueInformation.json +โ”œโ”€โ”€ products/ +โ”‚ โ””โ”€โ”€ starter/ +โ”‚ โ”œโ”€โ”€ productInformation.json +โ”‚ โ”œโ”€โ”€ policy.xml +โ”‚ โ””โ”€โ”€ apis.json +โ””โ”€โ”€ policy.xml โ† global service policy +``` + +Resources are stored as plain JSON (exactly as returned by the APIM Management API) so that any future APIM properties are automatically preserved during extract-publish round-trips without requiring tool updates. From e5a8cba7f49b509e0c33bd0e055563430104b75a Mon Sep 17 00:00:00 2001 From: Elizabeth Maher Date: Mon, 11 May 2026 19:19:27 +0000 Subject: [PATCH 03/13] updating devcontainer to periodically run 'git fetch' --- .devcontainer/devcontainer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4b71b7d6..bd4ad51a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -15,6 +15,7 @@ "vscode": { "settings": { "terminal.integrated.defaultProfile.linux": "bash", + "git.autofetch": true, "editor.formatOnSave": true, "editor.defaultFormatter": "dbaeumer.vscode-eslint", "eslint.format.enable": true, From 1c5f323832fcbb1d4aa992fd9d92af023211d7b3 Mon Sep 17 00:00:00 2001 From: Elizabeth Maher Date: Mon, 11 May 2026 20:20:59 +0000 Subject: [PATCH 04/13] Adding mermaid extension --- .devcontainer/devcontainer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index bd4ad51a..f6c1e5fb 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -25,6 +25,7 @@ }, "extensions": [ "dbaeumer.vscode-eslint", + "bierner.markdown-mermaid", "ms-vscode.vscode-typescript-next", "vitest.explorer", "GitHub.vscode-pull-request-github", From 848f25945f637172583d6853667b1a46d8ec60d2 Mon Sep 17 00:00:00 2001 From: Elizabeth Maher Date: Mon, 11 May 2026 20:21:13 +0000 Subject: [PATCH 05/13] updating config as code chart --- ...2-icon-service-API-Management-Services.svg | 1 + docs/architecture.md | 72 +++++++------------ 2 files changed, 26 insertions(+), 47 deletions(-) create mode 100644 docs/10042-icon-service-API-Management-Services.svg diff --git a/docs/10042-icon-service-API-Management-Services.svg b/docs/10042-icon-service-API-Management-Services.svg new file mode 100644 index 00000000..69f5998c --- /dev/null +++ b/docs/10042-icon-service-API-Management-Services.svg @@ -0,0 +1 @@ +Icon-web-42 \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index 910ed15e..e8a4a679 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -12,24 +12,29 @@ The diagram below shows how `apiops` fits into a typical team workflow: ```mermaid flowchart LR + classDef cmd font-family:monospace + dev(["๐Ÿ‘ค Developer"]) subgraph repo["Git Repository"] - artifacts["๐Ÿ“ APIM Artifacts\n(JSON + XML)"] - ci["โš™๏ธ CI/CD Workflows\n(GitHub Actions /\nAzure DevOps)"] + init_op(["apiops init"]):::cmd + artifacts["๐Ÿ“ apim-artifacts
(JSON + XML)"] + ci["โš™๏ธ CI/CD Workflows
(GitHub Actions /
Azure DevOps)"] end subgraph azure["Azure"] - apim_src["๐Ÿ”ต Source APIM\n(e.g. Dev)"] - apim_stg["๐ŸŸก APIM\n(Staging)"] - apim_prd["๐Ÿ”ด APIM\n(Production)"] + apim_src["
API Management resource"] + apim_dst["
API Management resource"] end - dev -- "apiops extract" --> artifacts - dev -- "apiops init" --> ci - apim_src -. "reads config" .-> artifacts - ci -- "apiops publish" --> apim_stg - ci -- "apiops publish\n(with overrides)" --> apim_prd + dev --> init_op + init_op --> ci + ci --> extract_op + apim_src -.-> extract_op + extract_op(["apiops extract"]):::cmd --> artifacts + ci --> publish_op + artifacts -.-> publish_op + publish_op(["apiops publish"]):::cmd --> apim_dst ``` | Step | Command | Description | @@ -53,30 +58,30 @@ flowchart TB end subgraph auth["Authentication (@azure/identity)"] - dac["DefaultAzureCredential\nOIDC ยท Service Principal\nManaged Identity ยท Azure CLI"] + dac["DefaultAzureCredential
OIDC ยท Service Principal
Managed Identity ยท Azure CLI"] end subgraph services["Services"] direction TB - extract_svc["Extract Service\n(parallel by dependency tier)"] + extract_svc["Extract Service
(parallel by dependency tier)"] filter_svc["Filter + Transitive Resolver"] - publish_svc["Publish Service\n(dependency-ordered PUT / DELETE)"] - override_svc["Override Merger\n(per-environment config)"] - git_svc["Git Diff Service\n(incremental publish)"] + publish_svc["Publish Service
(dependency-ordered PUT / DELETE)"] + override_svc["Override Merger
(per-environment config)"] + git_svc["Git Diff Service
(incremental publish)"] dry_svc["Dry-run Reporter"] - init_svc["Init Service\n(CI/CD scaffolding)"] + init_svc["Init Service
(CI/CD scaffolding)"] end subgraph clients["Clients"] - apim_client["APIM REST Client\n(Azure Management API)"] - store["Artifact Store\n(Local Filesystem)"] + apim_client["APIM REST Client
(Azure Management API)"] + store["Artifact Store
(Local Filesystem)"] end subgraph external["External Systems"] azure_apim[("Azure APIM")] - local_files[("Artifact Files\nJSON ยท XML ยท YAML")] + local_files[("Artifact Files
JSON ยท XML ยท YAML")] git_repo[("Git Repository")] cicd_files[("CI/CD Workflow Files")] end @@ -104,7 +109,7 @@ flowchart TB ### Extract flow -`apiops extract` fetches every resource type from the APIM Management API and writes each resource to a corresponding artifact file on disk. Extraction is parallelized across independent resource types and can be narrowed with a filter file; transitive dependencies (e.g. backends referenced by a policy) are automatically included. +`apiops extract` fetches every resource type from the APIM Management API and writes each resource to a corresponding artifact file on disk. Extraction is parallelized across independent resource types and can be narrowed with a filter file; transitive dependencies (e.g. backends referenced by a policy) are automatically included. Resources are stored as plain JSON (exactly as returned by the APIM Management API) so that any future APIM properties are automatically preserved during extract-publish round-trips without requiring tool updates. ### Publish flow @@ -134,30 +139,3 @@ flowchart TB No secrets are required when running in GitHub Actions workflows generated by `apiops init` โ€” authentication is handled entirely via OIDC federated credentials. --- - -## Artifact File Layout - -``` -apim-artifacts/ -โ”œโ”€โ”€ apis/ -โ”‚ โ””โ”€โ”€ orders-api/ -โ”‚ โ”œโ”€โ”€ apiInformation.json -โ”‚ โ”œโ”€โ”€ policy.xml -โ”‚ โ””โ”€โ”€ operations/ -โ”‚ โ””โ”€โ”€ get-order/ -โ”‚ โ””โ”€โ”€ policy.xml -โ”œโ”€โ”€ backends/ -โ”‚ โ””โ”€โ”€ orders-backend/ -โ”‚ โ””โ”€โ”€ backendInformation.json -โ”œโ”€โ”€ named values/ -โ”‚ โ””โ”€โ”€ orders-url/ -โ”‚ โ””โ”€โ”€ namedValueInformation.json -โ”œโ”€โ”€ products/ -โ”‚ โ””โ”€โ”€ starter/ -โ”‚ โ”œโ”€โ”€ productInformation.json -โ”‚ โ”œโ”€โ”€ policy.xml -โ”‚ โ””โ”€โ”€ apis.json -โ””โ”€โ”€ policy.xml โ† global service policy -``` - -Resources are stored as plain JSON (exactly as returned by the APIM Management API) so that any future APIM properties are automatically preserved during extract-publish round-trips without requiring tool updates. From d8c947281e75821ba5d80c93e41826c0aec503b1 Mon Sep 17 00:00:00 2001 From: Elizabeth Maher Date: Mon, 11 May 2026 20:32:39 +0000 Subject: [PATCH 06/13] Updating component architecture diagram --- docs/architecture.md | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index e8a4a679..6e482017 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -57,10 +57,6 @@ flowchart TB init_cmd["init"] end - subgraph auth["Authentication (@azure/identity)"] - dac["DefaultAzureCredential
OIDC ยท Service Principal
Managed Identity ยท Azure CLI"] - end - subgraph services["Services"] direction TB extract_svc["Extract Service
(parallel by dependency tier)"] @@ -76,14 +72,17 @@ flowchart TB subgraph clients["Clients"] apim_client["APIM REST Client
(Azure Management API)"] - store["Artifact Store
(Local Filesystem)"] + store["Artifact Store"] + end + + subgraph auth["Authentication"] + auth_pkg["@azure/identity"] end subgraph external["External Systems"] - azure_apim[("Azure APIM")] - local_files[("Artifact Files
JSON ยท XML ยท YAML")] + azure_apim[("
Azure API Management")] + local_files[("Artifact Files
(Local Filesystem)")] git_repo[("Git Repository")] - cicd_files[("CI/CD Workflow Files")] end extract_cmd --> extract_svc @@ -100,11 +99,11 @@ flowchart TB publish_svc --> apim_client publish_svc --> store - apim_client --> auth - auth --> azure_apim + apim_client --> auth_pkg + auth_pkg --> azure_apim store <--> local_files git_svc --> git_repo - init_svc --> cicd_files + init_svc --> git_repo ``` ### Extract flow From e4365dc055c349d49f5d6c2359e6b31466a9dc77 Mon Sep 17 00:00:00 2001 From: Elizabeth Maher Date: Tue, 12 May 2026 11:00:42 +0000 Subject: [PATCH 07/13] Adding icons --- docs/10261-icon-service-Azure-DevOps.svg | 1 + docs/architecture.md | 86 ++++++++++++------------ 2 files changed, 43 insertions(+), 44 deletions(-) create mode 100644 docs/10261-icon-service-Azure-DevOps.svg diff --git a/docs/10261-icon-service-Azure-DevOps.svg b/docs/10261-icon-service-Azure-DevOps.svg new file mode 100644 index 00000000..3d4a462f --- /dev/null +++ b/docs/10261-icon-service-Azure-DevOps.svg @@ -0,0 +1 @@ +Icon-devops-261 \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index 6e482017..d3ebe16c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,38 +10,56 @@ The diagram below shows how `apiops` fits into a typical team workflow: +_Icon attribution: Azure Architecture Icons (https://learn.microsoft.com/en-us/azure/architecture/icons/) and Font Awesome Free (https://fontawesome.com/)._ + ```mermaid flowchart LR classDef cmd font-family:monospace - dev(["๐Ÿ‘ค Developer"]) - - subgraph repo["Git Repository"] - init_op(["apiops init"]):::cmd - artifacts["๐Ÿ“ apim-artifacts
(JSON + XML)"] - ci["โš™๏ธ CI/CD Workflows
(GitHub Actions /
Azure DevOps)"] + dev(["Dev"]) + init_op(["apiops init"]):::cmd + extract_op(["apiops extract"]):::cmd + publish_op(["apiops publish"]):::cmd + pr["
Pull Request"] + merge_op["
Merge"] + + subgraph repo[" GitHub / Azure DevOps"] + artifacts["
apim-artifacts"] + subgraph ci["
CI/CD Workflows"] + direction TB + extract_pipeline["extract"] + publish_pipeline["publish"] + extract_pipeline --- publish_pipeline + end end subgraph azure["Azure"] - apim_src["
API Management resource"] - apim_dst["
API Management resource"] + direction LR + apim_src["
API Management
source"] + apim_dst["
API Management
target"] end - dev --> init_op - init_op --> ci - ci --> extract_op - apim_src -.-> extract_op - extract_op(["apiops extract"]):::cmd --> artifacts - ci --> publish_op - artifacts -.-> publish_op - publish_op(["apiops publish"]):::cmd --> apim_dst + dev -- "Step 1" --> init_op --> ci + dev -- "Step 2" --> extract_pipeline --> extract_op + apim_src --> extract_op --> artifacts + ci -- "Step 3" --> pr + pr -- "Step 4" --> merge_op + merge_op -- "Step 5" --> publish_pipeline --> publish_op + artifacts --> publish_op --> apim_dst ``` | Step | Command | Description | |------|---------|-------------| | 1 | `apiops init` | Scaffolds the Git repository with CI/CD workflow files and an identity setup guide | | 2 | `apiops extract` | Reads the running APIM configuration and writes it to local artifact files | -| 3 | `apiops publish` | Reads artifact files and creates/updates/deletes resources in the target APIM | +| 3 | Pull Request | Developer submits extracted artifact changes for review | +| 4 | Merge | Approved changes are merged | +| 5 | `apiops publish` | On merge, the publish workflow runs and applies artifact files to the target API Management instance | + +### Icon Usage + +> [!NOTE] +> Chart uses [Azure Architecture Icons ](https://learn.microsoft.com/en-us/azure/architecture/icons/) and GitHub icons from [Font Awesome](https://fontawesome.com/). --- @@ -81,8 +99,8 @@ flowchart TB subgraph external["External Systems"] azure_apim[("
Azure API Management")] - local_files[("Artifact Files
(Local Filesystem)")] - git_repo[("Git Repository")] + local_files[("
Artifact Files
(Local Filesystem)")] + git_repo[(" GitHub / Azure DevOps")] end extract_cmd --> extract_svc @@ -106,34 +124,14 @@ flowchart TB init_svc --> git_repo ``` -### Extract flow - -`apiops extract` fetches every resource type from the APIM Management API and writes each resource to a corresponding artifact file on disk. Extraction is parallelized across independent resource types and can be narrowed with a filter file; transitive dependencies (e.g. backends referenced by a policy) are automatically included. Resources are stored as plain JSON (exactly as returned by the APIM Management API) so that any future APIM properties are automatically preserved during extract-publish round-trips without requiring tool updates. - -### Publish flow - -`apiops publish` reads artifact files from disk and applies them to the target APIM instance in topological dependency order (backends before APIs, APIs before products, etc.). Three optional modes reduce blast radius: - -- **`--dry-run`** โ€” prints the plan without making any changes -- **`--overrides `** โ€” merges per-environment values (backend URLs, named-value secrets) before publishing -- **`--commit-id `** โ€” incremental mode; only resources whose artifact files changed in that Git commit are published - -### Init flow - -`apiops init` scaffolds the repository with ready-to-use GitHub Actions or Azure DevOps workflow files and generates an `identity-setup.prompt.md` guide for configuring OIDC federated credentials โ€” no client secrets required. - ---- - ## Authentication -`apiops` uses [`DefaultAzureCredential`](https://learn.microsoft.com/azure/developer/javascript/sdk/authentication/overview) from the `@azure/identity` SDK. Credentials are tried in this order: +`apiops` uses [`DefaultAzureCredential`](https://learn.microsoft.com/javascript/api/%40azure/identity/defaultazurecredential?view=azure-node-latest) from the `@azure/identity` SDK. + +For the up-to-date credential chain and authentication behavior, see Microsoft docs: -| Credential | Typical use | -|---|---| -| Workload Identity (OIDC) | GitHub Actions / Azure Pipelines | -| Service Principal (env vars or flags) | Legacy CI/CD, scripts | -| Managed Identity | Azure-hosted runners, VMs, App Service | -| Azure CLI / Azure Developer CLI | Local development | +- [Credential chains in the Azure Identity library for JavaScript](https://learn.microsoft.com/azure/developer/javascript/sdk/authentication/credential-chains) +- [Authenticate JavaScript apps to Azure services during local development](https://learn.microsoft.com/azure/developer/javascript/sdk/authentication/local-development-environment-service-principal) No secrets are required when running in GitHub Actions workflows generated by `apiops init` โ€” authentication is handled entirely via OIDC federated credentials. From e679fd615a6a4c576b6311bd9865fe19e5c5b992 Mon Sep 17 00:00:00 2001 From: Elizabeth Maher Date: Tue, 12 May 2026 04:08:24 -0700 Subject: [PATCH 08/13] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/architecture.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/architecture.md b/docs/architecture.md index d3ebe16c..113c6f8e 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -133,6 +133,8 @@ For the up-to-date credential chain and authentication behavior, see Microsoft d - [Credential chains in the Azure Identity library for JavaScript](https://learn.microsoft.com/azure/developer/javascript/sdk/authentication/credential-chains) - [Authenticate JavaScript apps to Azure services during local development](https://learn.microsoft.com/azure/developer/javascript/sdk/authentication/local-development-environment-service-principal) -No secrets are required when running in GitHub Actions workflows generated by `apiops init` โ€” authentication is handled entirely via OIDC federated credentials. +GitHub Actions workflows generated by `apiops init` use OIDC federated credentials for Azure authentication, which means you do not need to store an Azure client secret for `azure/login@v2`. + +However, the generated workflows still require GitHub Actions secret or environment values such as `AZURE_CLIENT_ID`, `AZURE_TENANT_ID`, `AZURE_SUBSCRIPTION_ID`, and any APIM environment-specific secrets referenced by the workflow templates. --- From cf491e3e22f18cd094a5f2528595069131ed6c99 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 11:14:57 +0000 Subject: [PATCH 09/13] docs: replace external Font Awesome SVG URLs with fa: notation in Mermaid diagrams Agent-Logs-Url: https://github.com/Azure/apiops-cli/sessions/6362b9de-dfe9-46fc-81bb-5cb92a322e8a Co-authored-by: EMaher <9244742+EMaher@users.noreply.github.com> --- ...2-icon-service-API-Management-Services.svg | 1 - docs/10261-icon-service-Azure-DevOps.svg | 1 - docs/architecture.md | 29 +++++++------------ 3 files changed, 11 insertions(+), 20 deletions(-) delete mode 100644 docs/10042-icon-service-API-Management-Services.svg delete mode 100644 docs/10261-icon-service-Azure-DevOps.svg diff --git a/docs/10042-icon-service-API-Management-Services.svg b/docs/10042-icon-service-API-Management-Services.svg deleted file mode 100644 index 69f5998c..00000000 --- a/docs/10042-icon-service-API-Management-Services.svg +++ /dev/null @@ -1 +0,0 @@ -Icon-web-42 \ No newline at end of file diff --git a/docs/10261-icon-service-Azure-DevOps.svg b/docs/10261-icon-service-Azure-DevOps.svg deleted file mode 100644 index 3d4a462f..00000000 --- a/docs/10261-icon-service-Azure-DevOps.svg +++ /dev/null @@ -1 +0,0 @@ -Icon-devops-261 \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index 113c6f8e..f48e11cd 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -10,22 +10,20 @@ The diagram below shows how `apiops` fits into a typical team workflow: -_Icon attribution: Azure Architecture Icons (https://learn.microsoft.com/en-us/azure/architecture/icons/) and Font Awesome Free (https://fontawesome.com/)._ - ```mermaid flowchart LR classDef cmd font-family:monospace - dev(["Dev"]) + dev(["fa:fa-user Dev"]) init_op(["apiops init"]):::cmd extract_op(["apiops extract"]):::cmd publish_op(["apiops publish"]):::cmd - pr["
Pull Request"] - merge_op["
Merge"] + pr["fa:fa-code-pull-request Pull Request"] + merge_op["fa:fa-code-merge Merge"] - subgraph repo[" GitHub / Azure DevOps"] - artifacts["
apim-artifacts"] - subgraph ci["
CI/CD Workflows"] + subgraph repo["fa:fa-github GitHub / Azure DevOps"] + artifacts["fa:fa-folder apim-artifacts"] + subgraph ci["fa:fa-gears CI/CD Workflows"] direction TB extract_pipeline["extract"] publish_pipeline["publish"] @@ -35,8 +33,8 @@ flowchart LR subgraph azure["Azure"] direction LR - apim_src["
API Management
source"] - apim_dst["
API Management
target"] + apim_src["API Management
source"] + apim_dst["API Management
target"] end dev -- "Step 1" --> init_op --> ci @@ -56,11 +54,6 @@ flowchart LR | 4 | Merge | Approved changes are merged | | 5 | `apiops publish` | On merge, the publish workflow runs and applies artifact files to the target API Management instance | -### Icon Usage - -> [!NOTE] -> Chart uses [Azure Architecture Icons ](https://learn.microsoft.com/en-us/azure/architecture/icons/) and GitHub icons from [Font Awesome](https://fontawesome.com/). - --- ## Component Architecture @@ -98,9 +91,9 @@ flowchart TB end subgraph external["External Systems"] - azure_apim[("
Azure API Management")] - local_files[("
Artifact Files
(Local Filesystem)")] - git_repo[(" GitHub / Azure DevOps")] + azure_apim[("Azure API Management")] + local_files[("fa:fa-folder Artifact Files\n(Local Filesystem)")] + git_repo[("fa:fa-github GitHub / Azure DevOps")] end extract_cmd --> extract_svc From 9acadc8fd88bbc87884d71009aeda3839fff7fc7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 11:15:13 +0000 Subject: [PATCH 10/13] docs: restore Icon Usage note in architecture.md Agent-Logs-Url: https://github.com/Azure/apiops-cli/sessions/6362b9de-dfe9-46fc-81bb-5cb92a322e8a Co-authored-by: EMaher <9244742+EMaher@users.noreply.github.com> --- docs/architecture.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/architecture.md b/docs/architecture.md index f48e11cd..166cc64e 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -54,6 +54,11 @@ flowchart LR | 4 | Merge | Approved changes are merged | | 5 | `apiops publish` | On merge, the publish workflow runs and applies artifact files to the target API Management instance | +### Icon Usage + +> [!NOTE] +> Diagrams use icons from [Font Awesome Free](https://fontawesome.com/) via Mermaid's built-in `fa:` syntax. + --- ## Component Architecture From 1828f17086150d20bf571af578ccbad13ccf9ac9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 12 May 2026 11:18:11 +0000 Subject: [PATCH 11/13] docs: keep Azure Architecture Icons link in Icon Usage note Agent-Logs-Url: https://github.com/Azure/apiops-cli/sessions/f5501a00-ad6c-4752-8727-eacb5ab8df74 Co-authored-by: EMaher <9244742+EMaher@users.noreply.github.com> --- docs/architecture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture.md b/docs/architecture.md index 166cc64e..34ffd189 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -57,7 +57,7 @@ flowchart LR ### Icon Usage > [!NOTE] -> Diagrams use icons from [Font Awesome Free](https://fontawesome.com/) via Mermaid's built-in `fa:` syntax. +> Chart uses Azure Architecture Icons and [Font Awesome Free](https://fontawesome.com/) via Mermaid's built-in `fa:` syntax. --- From 5cf407c2bd9483845318639b3b6b51ad250b1875 Mon Sep 17 00:00:00 2001 From: Elizabeth Maher Date: Tue, 12 May 2026 11:23:50 +0000 Subject: [PATCH 12/13] fixing icon attribution --- docs/architecture.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 34ffd189..cf6ae46c 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,7 +2,7 @@ ## Overview -`apiops` implements a **configuration-as-code** workflow for Azure API Management (APIM). Configuration is extracted from a running APIM instance into version-controlled artifact files. Those files become the source of truth for publishing to one or more environments, driven by a CI/CD pipeline. +`apiops` implements a **configuration-as-code** workflow for Azure API Management. Configuration is extracted from a running APIM instance into version-controlled artifact files. Those files become the source of truth for publishing to one or more environments, driven by a CI/CD pipeline. --- @@ -54,10 +54,8 @@ flowchart LR | 4 | Merge | Approved changes are merged | | 5 | `apiops publish` | On merge, the publish workflow runs and applies artifact files to the target API Management instance | -### Icon Usage - > [!NOTE] -> Chart uses Azure Architecture Icons and [Font Awesome Free](https://fontawesome.com/) via Mermaid's built-in `fa:` syntax. +> Chart uses Azure Architecture Icons and GitHub icons from [Font Awesome](https://fontawesome.com/). --- From c50e2c9b6ec995a9f9ce84a9f3e29de9ff416c30 Mon Sep 17 00:00:00 2001 From: Elizabeth Maher Date: Thu, 14 May 2026 18:45:46 +0000 Subject: [PATCH 13/13] Changing config-as-code to sequence diagram. --- docs/architecture.md | 92 ++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index cf6ae46c..08c20f48 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -8,54 +8,56 @@ ## Configuration-as-Code Workflow -The diagram below shows how `apiops` fits into a typical team workflow: +The sequence diagram below shows how `apiops` fits into a typical team workflow, including all commands and affected resources: ```mermaid -flowchart LR - classDef cmd font-family:monospace - - dev(["fa:fa-user Dev"]) - init_op(["apiops init"]):::cmd - extract_op(["apiops extract"]):::cmd - publish_op(["apiops publish"]):::cmd - pr["fa:fa-code-pull-request Pull Request"] - merge_op["fa:fa-code-merge Merge"] - - subgraph repo["fa:fa-github GitHub / Azure DevOps"] - artifacts["fa:fa-folder apim-artifacts"] - subgraph ci["fa:fa-gears CI/CD Workflows"] - direction TB - extract_pipeline["extract"] - publish_pipeline["publish"] - extract_pipeline --- publish_pipeline - end +sequenceDiagram + participant dev as Developer + participant git as Repository
(GitHub/
Azure DevOps) + participant ci as CI/CD Pipeline + participant apim_src as Source
API Management + participant apim_dst as Target
API Management + + rect rgb(200, 220, 255) + note over dev: Step 1: Initialize + dev->>git: Command: apiops init + git->>git: Create CI/CD workflow files
(extract & publish pipelines) end - subgraph azure["Azure"] - direction LR - apim_src["API Management
source"] - apim_dst["API Management
target"] + rect rgb(200, 255, 220) + note over dev: Step 2: Extract Configuration + dev->>ci: Run extract pipeline + note over ci: Command: apiops extract + ci->>apim_src: Read configuration + apim_src-->>ci: Current APIM config + ci->>git: Write to apim-artifacts/ + git->>dev: Show extracted changes end - dev -- "Step 1" --> init_op --> ci - dev -- "Step 2" --> extract_pipeline --> extract_op - apim_src --> extract_op --> artifacts - ci -- "Step 3" --> pr - pr -- "Step 4" --> merge_op - merge_op -- "Step 5" --> publish_pipeline --> publish_op - artifacts --> publish_op --> apim_dst -``` + rect rgb(255, 240, 200) + note over dev: Step 3-4: Review & Merge + dev->>git: Create Pull Request + note over git: Code review & approval + dev->>git: Merge to main branch + end -| Step | Command | Description | -|------|---------|-------------| -| 1 | `apiops init` | Scaffolds the Git repository with CI/CD workflow files and an identity setup guide | -| 2 | `apiops extract` | Reads the running APIM configuration and writes it to local artifact files | -| 3 | Pull Request | Developer submits extracted artifact changes for review | -| 4 | Merge | Approved changes are merged | -| 5 | `apiops publish` | On merge, the publish workflow runs and applies artifact files to the target API Management instance | + rect rgb(255, 220, 220) + note over ci: Step 5: Publish Configuration + git->>ci: Trigger publish pipeline + note over ci: Command: apiops publish + ci->>git: Read apim-artifacts/ + git-->>ci: Artifact files + ci->>apim_dst: Apply configuration to target + apim_dst-->>ci: Updated successfully + end +``` -> [!NOTE] -> Chart uses Azure Architecture Icons and GitHub icons from [Font Awesome](https://fontawesome.com/). +| Step | Command | Affected Resources | Description | +|------|---------|-------------------|-------------| +| 1 | `apiops init` | Repository | Scaffolds the Git repository with CI/CD workflow files and an identity setup guide | +| 2 | `apiops extract` | Source APIM, apim-artifacts/ | Reads the running APIM configuration and writes it to local artifact files | +| 3-4 | โ€” | Repository (PR & Merge) | Developer submits extracted artifact changes for review and approves merge | +| 5 | `apiops publish` | apim-artifacts/, Target APIM | On merge, the publish workflow runs and applies artifact files to the target API Management instance | --- @@ -73,10 +75,10 @@ flowchart TB subgraph services["Services"] direction TB - extract_svc["Extract Service
(parallel by dependency tier)"] + extract_svc["Extract Service
(parallel by
dependency tier)"] filter_svc["Filter + Transitive Resolver"] - publish_svc["Publish Service
(dependency-ordered PUT / DELETE)"] + publish_svc["Publish Service
(dependency-ordered
PUT / DELETE)"] override_svc["Override Merger
(per-environment config)"] git_svc["Git Diff Service
(incremental publish)"] dry_svc["Dry-run Reporter"] @@ -85,7 +87,7 @@ flowchart TB end subgraph clients["Clients"] - apim_client["APIM REST Client
(Azure Management API)"] + apim_client["API Management REST Client"] store["Artifact Store"] end @@ -94,8 +96,8 @@ flowchart TB end subgraph external["External Systems"] - azure_apim[("Azure API Management")] - local_files[("fa:fa-folder Artifact Files\n(Local Filesystem)")] + azure_apim[("API Management")] + local_files[("fa:fa-folder Artifact Files
(Local Filesystem)")] git_repo[("fa:fa-github GitHub / Azure DevOps")] end