@peterhauge/apiops-cli 0.1.3-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +135 -0
- package/dist/cli/extract-command.d.ts +12 -0
- package/dist/cli/extract-command.d.ts.map +1 -0
- package/dist/cli/extract-command.js +157 -0
- package/dist/cli/extract-command.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +74 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-command.d.ts +11 -0
- package/dist/cli/init-command.d.ts.map +1 -0
- package/dist/cli/init-command.js +87 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/cli/publish-command.d.ts +12 -0
- package/dist/cli/publish-command.d.ts.map +1 -0
- package/dist/cli/publish-command.js +159 -0
- package/dist/cli/publish-command.js.map +1 -0
- package/dist/clients/apim-client.d.ts +110 -0
- package/dist/clients/apim-client.d.ts.map +1 -0
- package/dist/clients/apim-client.js +586 -0
- package/dist/clients/apim-client.js.map +1 -0
- package/dist/clients/artifact-store.d.ts +23 -0
- package/dist/clients/artifact-store.d.ts.map +1 -0
- package/dist/clients/artifact-store.js +188 -0
- package/dist/clients/artifact-store.js.map +1 -0
- package/dist/clients/iapim-client.d.ts +52 -0
- package/dist/clients/iapim-client.d.ts.map +1 -0
- package/dist/clients/iapim-client.js +6 -0
- package/dist/clients/iapim-client.js.map +1 -0
- package/dist/clients/iartifact-store.d.ts +50 -0
- package/dist/clients/iartifact-store.d.ts.map +1 -0
- package/dist/clients/iartifact-store.js +6 -0
- package/dist/clients/iartifact-store.js.map +1 -0
- package/dist/lib/auto-generated.d.ts +27 -0
- package/dist/lib/auto-generated.d.ts.map +1 -0
- package/dist/lib/auto-generated.js +34 -0
- package/dist/lib/auto-generated.js.map +1 -0
- package/dist/lib/cloud-config.d.ts +29 -0
- package/dist/lib/cloud-config.d.ts.map +1 -0
- package/dist/lib/cloud-config.js +60 -0
- package/dist/lib/cloud-config.js.map +1 -0
- package/dist/lib/config-loader.d.ts +21 -0
- package/dist/lib/config-loader.d.ts.map +1 -0
- package/dist/lib/config-loader.js +131 -0
- package/dist/lib/config-loader.js.map +1 -0
- package/dist/lib/dependency-graph.d.ts +43 -0
- package/dist/lib/dependency-graph.d.ts.map +1 -0
- package/dist/lib/dependency-graph.js +163 -0
- package/dist/lib/dependency-graph.js.map +1 -0
- package/dist/lib/exit-codes.d.ts +27 -0
- package/dist/lib/exit-codes.d.ts.map +1 -0
- package/dist/lib/exit-codes.js +33 -0
- package/dist/lib/exit-codes.js.map +1 -0
- package/dist/lib/logger.d.ts +39 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +128 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/parallel-runner.d.ts +38 -0
- package/dist/lib/parallel-runner.d.ts.map +1 -0
- package/dist/lib/parallel-runner.js +70 -0
- package/dist/lib/parallel-runner.js.map +1 -0
- package/dist/lib/resource-path.d.ts +205 -0
- package/dist/lib/resource-path.d.ts.map +1 -0
- package/dist/lib/resource-path.js +401 -0
- package/dist/lib/resource-path.js.map +1 -0
- package/dist/lib/resource-uri.d.ts +40 -0
- package/dist/lib/resource-uri.d.ts.map +1 -0
- package/dist/lib/resource-uri.js +86 -0
- package/dist/lib/resource-uri.js.map +1 -0
- package/dist/lib/user-agent.d.ts +2 -0
- package/dist/lib/user-agent.d.ts.map +1 -0
- package/dist/lib/user-agent.js +5 -0
- package/dist/lib/user-agent.js.map +1 -0
- package/dist/models/config.d.ts +83 -0
- package/dist/models/config.d.ts.map +1 -0
- package/dist/models/config.js +6 -0
- package/dist/models/config.js.map +1 -0
- package/dist/models/resource-types.d.ts +66 -0
- package/dist/models/resource-types.d.ts.map +1 -0
- package/dist/models/resource-types.js +243 -0
- package/dist/models/resource-types.js.map +1 -0
- package/dist/models/types.d.ts +47 -0
- package/dist/models/types.d.ts.map +1 -0
- package/dist/models/types.js +6 -0
- package/dist/models/types.js.map +1 -0
- package/dist/services/api-extractor.d.ts +36 -0
- package/dist/services/api-extractor.d.ts.map +1 -0
- package/dist/services/api-extractor.js +319 -0
- package/dist/services/api-extractor.js.map +1 -0
- package/dist/services/api-publisher.d.ts +18 -0
- package/dist/services/api-publisher.d.ts.map +1 -0
- package/dist/services/api-publisher.js +290 -0
- package/dist/services/api-publisher.js.map +1 -0
- package/dist/services/delete-unmatched-service.d.ts +17 -0
- package/dist/services/delete-unmatched-service.d.ts.map +1 -0
- package/dist/services/delete-unmatched-service.js +143 -0
- package/dist/services/delete-unmatched-service.js.map +1 -0
- package/dist/services/dry-run-reporter.d.ts +30 -0
- package/dist/services/dry-run-reporter.d.ts.map +1 -0
- package/dist/services/dry-run-reporter.js +111 -0
- package/dist/services/dry-run-reporter.js.map +1 -0
- package/dist/services/extract-service.d.ts +47 -0
- package/dist/services/extract-service.d.ts.map +1 -0
- package/dist/services/extract-service.js +374 -0
- package/dist/services/extract-service.js.map +1 -0
- package/dist/services/filter-service.d.ts +29 -0
- package/dist/services/filter-service.d.ts.map +1 -0
- package/dist/services/filter-service.js +143 -0
- package/dist/services/filter-service.js.map +1 -0
- package/dist/services/git-diff-service.d.ts +23 -0
- package/dist/services/git-diff-service.d.ts.map +1 -0
- package/dist/services/git-diff-service.js +135 -0
- package/dist/services/git-diff-service.js.map +1 -0
- package/dist/services/identity-guide-service.d.ts +11 -0
- package/dist/services/identity-guide-service.d.ts.map +1 -0
- package/dist/services/identity-guide-service.js +227 -0
- package/dist/services/identity-guide-service.js.map +1 -0
- package/dist/services/init-service.d.ts +16 -0
- package/dist/services/init-service.d.ts.map +1 -0
- package/dist/services/init-service.js +304 -0
- package/dist/services/init-service.js.map +1 -0
- package/dist/services/keyvault-checker.d.ts +58 -0
- package/dist/services/keyvault-checker.d.ts.map +1 -0
- package/dist/services/keyvault-checker.js +390 -0
- package/dist/services/keyvault-checker.js.map +1 -0
- package/dist/services/override-merger.d.ts +20 -0
- package/dist/services/override-merger.d.ts.map +1 -0
- package/dist/services/override-merger.js +102 -0
- package/dist/services/override-merger.js.map +1 -0
- package/dist/services/product-extractor.d.ts +26 -0
- package/dist/services/product-extractor.d.ts.map +1 -0
- package/dist/services/product-extractor.js +141 -0
- package/dist/services/product-extractor.js.map +1 -0
- package/dist/services/product-publisher.d.ts +15 -0
- package/dist/services/product-publisher.d.ts.map +1 -0
- package/dist/services/product-publisher.js +113 -0
- package/dist/services/product-publisher.js.map +1 -0
- package/dist/services/prompt-service.d.ts +13 -0
- package/dist/services/prompt-service.d.ts.map +1 -0
- package/dist/services/prompt-service.js +69 -0
- package/dist/services/prompt-service.js.map +1 -0
- package/dist/services/publish-service.d.ts +31 -0
- package/dist/services/publish-service.d.ts.map +1 -0
- package/dist/services/publish-service.js +445 -0
- package/dist/services/publish-service.js.map +1 -0
- package/dist/services/resource-extractor.d.ts +52 -0
- package/dist/services/resource-extractor.d.ts.map +1 -0
- package/dist/services/resource-extractor.js +168 -0
- package/dist/services/resource-extractor.js.map +1 -0
- package/dist/services/resource-publisher.d.ts +23 -0
- package/dist/services/resource-publisher.d.ts.map +1 -0
- package/dist/services/resource-publisher.js +349 -0
- package/dist/services/resource-publisher.js.map +1 -0
- package/dist/services/secret-redactor.d.ts +20 -0
- package/dist/services/secret-redactor.d.ts.map +1 -0
- package/dist/services/secret-redactor.js +45 -0
- package/dist/services/secret-redactor.js.map +1 -0
- package/dist/services/transitive-resolver.d.ts +45 -0
- package/dist/services/transitive-resolver.d.ts.map +1 -0
- package/dist/services/transitive-resolver.js +177 -0
- package/dist/services/transitive-resolver.js.map +1 -0
- package/dist/services/workspace-extractor.d.ts +34 -0
- package/dist/services/workspace-extractor.d.ts.map +1 -0
- package/dist/services/workspace-extractor.js +120 -0
- package/dist/services/workspace-extractor.js.map +1 -0
- package/dist/templates/azure-devops/extract-pipeline.d.ts +9 -0
- package/dist/templates/azure-devops/extract-pipeline.d.ts.map +1 -0
- package/dist/templates/azure-devops/extract-pipeline.js +95 -0
- package/dist/templates/azure-devops/extract-pipeline.js.map +1 -0
- package/dist/templates/azure-devops/publish-pipeline.d.ts +10 -0
- package/dist/templates/azure-devops/publish-pipeline.d.ts.map +1 -0
- package/dist/templates/azure-devops/publish-pipeline.js +100 -0
- package/dist/templates/azure-devops/publish-pipeline.js.map +1 -0
- package/dist/templates/configs/filter-config.d.ts +6 -0
- package/dist/templates/configs/filter-config.d.ts.map +1 -0
- package/dist/templates/configs/filter-config.js +51 -0
- package/dist/templates/configs/filter-config.js.map +1 -0
- package/dist/templates/configs/override-config.d.ts +6 -0
- package/dist/templates/configs/override-config.d.ts.map +1 -0
- package/dist/templates/configs/override-config.js +45 -0
- package/dist/templates/configs/override-config.js.map +1 -0
- package/dist/templates/configs/package-json.d.ts +10 -0
- package/dist/templates/configs/package-json.d.ts.map +1 -0
- package/dist/templates/configs/package-json.js +19 -0
- package/dist/templates/configs/package-json.js.map +1 -0
- package/dist/templates/copilot/identity-setup-prompt.d.ts +13 -0
- package/dist/templates/copilot/identity-setup-prompt.d.ts.map +1 -0
- package/dist/templates/copilot/identity-setup-prompt.js +279 -0
- package/dist/templates/copilot/identity-setup-prompt.js.map +1 -0
- package/dist/templates/github-actions/extract-workflow.d.ts +9 -0
- package/dist/templates/github-actions/extract-workflow.d.ts.map +1 -0
- package/dist/templates/github-actions/extract-workflow.js +126 -0
- package/dist/templates/github-actions/extract-workflow.js.map +1 -0
- package/dist/templates/github-actions/publish-workflow.d.ts +10 -0
- package/dist/templates/github-actions/publish-workflow.d.ts.map +1 -0
- package/dist/templates/github-actions/publish-workflow.js +105 -0
- package/dist/templates/github-actions/publish-workflow.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T025: Transitive dependency resolver
|
|
3
|
+
* Scan policies for named value refs, backend refs, policy fragment refs.
|
|
4
|
+
* Scan apiInformation.json for apiVersionSetId.
|
|
5
|
+
* Fixed-point expansion; --no-transitive bypass.
|
|
6
|
+
*/
|
|
7
|
+
import { FilterConfig } from '../models/config.js';
|
|
8
|
+
import { ResourceType } from '../models/resource-types.js';
|
|
9
|
+
import { ResourceDescriptor } from '../models/types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Represents a discovered transitive dependency.
|
|
12
|
+
*/
|
|
13
|
+
export interface TransitiveDependency {
|
|
14
|
+
type: ResourceType;
|
|
15
|
+
name: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Scan policy XML content for references to other resources.
|
|
19
|
+
*
|
|
20
|
+
* Detects:
|
|
21
|
+
* - Named values: {{namedValueName}} syntax
|
|
22
|
+
* - Backends: <set-backend-service backend-id="backendName">
|
|
23
|
+
* - Policy fragments: <include-fragment fragment-id="fragmentName">
|
|
24
|
+
*/
|
|
25
|
+
export declare function scanPolicyReferences(policyXml: string): TransitiveDependency[];
|
|
26
|
+
/**
|
|
27
|
+
* Scan API information JSON for version set reference.
|
|
28
|
+
*/
|
|
29
|
+
export declare function scanApiVersionSetReference(apiJson: Record<string, unknown>): TransitiveDependency | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve transitive dependencies by expanding the extraction set
|
|
32
|
+
* until no new dependencies are found (fixed-point).
|
|
33
|
+
*
|
|
34
|
+
* @param extractedPolicies - Map of descriptor key to policy XML content
|
|
35
|
+
* @param extractedApis - Map of API name to API JSON (for version set refs)
|
|
36
|
+
* @param currentFilter - Current filter config to expand
|
|
37
|
+
* @returns Updated filter config with transitive dependencies included
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveTransitiveDependencies(extractedPolicies: Map<string, string>, extractedApis: Map<string, Record<string, unknown>>, currentFilter: FilterConfig): FilterConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Build a set of descriptors from transitive dependency scanning.
|
|
42
|
+
* Returns additional descriptors that should be extracted.
|
|
43
|
+
*/
|
|
44
|
+
export declare function findTransitiveDependencies(policies: Map<string, string>, apis: Map<string, Record<string, unknown>>): ResourceDescriptor[];
|
|
45
|
+
//# sourceMappingURL=transitive-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transitive-resolver.d.ts","sourceRoot":"","sources":["../../src/services/transitive-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAUxD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,oBAAoB,EAAE,CAkC9E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,oBAAoB,GAAG,SAAS,CAuBlC;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAC3C,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACnD,aAAa,EAAE,YAAY,GAC1B,YAAY,CAmCd;AAwCD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACzC,kBAAkB,EAAE,CA4BtB"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T025: Transitive dependency resolver
|
|
3
|
+
* Scan policies for named value refs, backend refs, policy fragment refs.
|
|
4
|
+
* Scan apiInformation.json for apiVersionSetId.
|
|
5
|
+
* Fixed-point expansion; --no-transitive bypass.
|
|
6
|
+
*/
|
|
7
|
+
import { ResourceType } from '../models/resource-types.js';
|
|
8
|
+
import { logger } from '../lib/logger.js';
|
|
9
|
+
/**
|
|
10
|
+
* Reference detection patterns for policy XML content.
|
|
11
|
+
*/
|
|
12
|
+
const NAMED_VALUE_PATTERN = /\{\{([^}]+)\}\}/g;
|
|
13
|
+
const BACKEND_PATTERN = /<set-backend-service\s+backend-id="([^"]+)"/g;
|
|
14
|
+
const FRAGMENT_PATTERN = /<include-fragment\s+fragment-id="([^"]+)"/g;
|
|
15
|
+
/**
|
|
16
|
+
* Scan policy XML content for references to other resources.
|
|
17
|
+
*
|
|
18
|
+
* Detects:
|
|
19
|
+
* - Named values: {{namedValueName}} syntax
|
|
20
|
+
* - Backends: <set-backend-service backend-id="backendName">
|
|
21
|
+
* - Policy fragments: <include-fragment fragment-id="fragmentName">
|
|
22
|
+
*/
|
|
23
|
+
export function scanPolicyReferences(policyXml) {
|
|
24
|
+
const dependencies = [];
|
|
25
|
+
// Named value references
|
|
26
|
+
for (const match of policyXml.matchAll(NAMED_VALUE_PATTERN)) {
|
|
27
|
+
if (match[1]) {
|
|
28
|
+
dependencies.push({
|
|
29
|
+
type: ResourceType.NamedValue,
|
|
30
|
+
name: match[1].trim(),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Backend references
|
|
35
|
+
for (const match of policyXml.matchAll(BACKEND_PATTERN)) {
|
|
36
|
+
if (match[1]) {
|
|
37
|
+
dependencies.push({
|
|
38
|
+
type: ResourceType.Backend,
|
|
39
|
+
name: match[1].trim(),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Policy fragment references
|
|
44
|
+
for (const match of policyXml.matchAll(FRAGMENT_PATTERN)) {
|
|
45
|
+
if (match[1]) {
|
|
46
|
+
dependencies.push({
|
|
47
|
+
type: ResourceType.PolicyFragment,
|
|
48
|
+
name: match[1].trim(),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return dependencies;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Scan API information JSON for version set reference.
|
|
56
|
+
*/
|
|
57
|
+
export function scanApiVersionSetReference(apiJson) {
|
|
58
|
+
const properties = apiJson.properties;
|
|
59
|
+
if (!properties) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const versionSetId = properties.apiVersionSetId;
|
|
63
|
+
if (!versionSetId) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
// Extract version set name from ARM resource ID
|
|
67
|
+
// Format: /subscriptions/.../apiVersionSets/{name}
|
|
68
|
+
const parts = versionSetId.split('/');
|
|
69
|
+
const name = parts[parts.length - 1];
|
|
70
|
+
if (!name) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
type: ResourceType.VersionSet,
|
|
75
|
+
name,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolve transitive dependencies by expanding the extraction set
|
|
80
|
+
* until no new dependencies are found (fixed-point).
|
|
81
|
+
*
|
|
82
|
+
* @param extractedPolicies - Map of descriptor key to policy XML content
|
|
83
|
+
* @param extractedApis - Map of API name to API JSON (for version set refs)
|
|
84
|
+
* @param currentFilter - Current filter config to expand
|
|
85
|
+
* @returns Updated filter config with transitive dependencies included
|
|
86
|
+
*/
|
|
87
|
+
export function resolveTransitiveDependencies(extractedPolicies, extractedApis, currentFilter) {
|
|
88
|
+
const expanded = { ...currentFilter };
|
|
89
|
+
let changed = true;
|
|
90
|
+
let iterations = 0;
|
|
91
|
+
const maxIterations = 10; // Safety limit
|
|
92
|
+
while (changed && iterations < maxIterations) {
|
|
93
|
+
changed = false;
|
|
94
|
+
iterations++;
|
|
95
|
+
// Scan all extracted policies for references
|
|
96
|
+
for (const [, policyXml] of extractedPolicies) {
|
|
97
|
+
const refs = scanPolicyReferences(policyXml);
|
|
98
|
+
for (const ref of refs) {
|
|
99
|
+
if (addToFilter(expanded, ref)) {
|
|
100
|
+
changed = true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Scan API information for version set references
|
|
105
|
+
for (const [, apiJson] of extractedApis) {
|
|
106
|
+
const versionSetRef = scanApiVersionSetReference(apiJson);
|
|
107
|
+
if (versionSetRef && addToFilter(expanded, versionSetRef)) {
|
|
108
|
+
changed = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (iterations > 1) {
|
|
113
|
+
logger.debug(`Transitive resolution completed in ${iterations} iterations`);
|
|
114
|
+
}
|
|
115
|
+
return expanded;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Add a transitive dependency to the filter config.
|
|
119
|
+
* Returns true if the filter was actually modified (new entry added).
|
|
120
|
+
*/
|
|
121
|
+
function addToFilter(filter, dep) {
|
|
122
|
+
const fieldMap = {
|
|
123
|
+
[ResourceType.NamedValue]: 'namedValueNames',
|
|
124
|
+
[ResourceType.Backend]: 'backendNames',
|
|
125
|
+
[ResourceType.PolicyFragment]: 'policyFragmentNames',
|
|
126
|
+
[ResourceType.VersionSet]: 'versionSetNames',
|
|
127
|
+
};
|
|
128
|
+
const field = fieldMap[dep.type];
|
|
129
|
+
if (!field) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
// Get current array; if undefined, the type is not filtered so no need to add
|
|
133
|
+
const current = filter[field];
|
|
134
|
+
if (current === undefined) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
// Check if already included (case-insensitive)
|
|
138
|
+
const lowerName = dep.name.toLowerCase();
|
|
139
|
+
if (current.some((n) => n.toLowerCase() === lowerName)) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
// Add to filter
|
|
143
|
+
filter[field] = [...current, dep.name];
|
|
144
|
+
logger.debug(`Transitive: added ${dep.type} "${dep.name}" to filter`);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Build a set of descriptors from transitive dependency scanning.
|
|
149
|
+
* Returns additional descriptors that should be extracted.
|
|
150
|
+
*/
|
|
151
|
+
export function findTransitiveDependencies(policies, apis) {
|
|
152
|
+
const dependencies = [];
|
|
153
|
+
const seen = new Set();
|
|
154
|
+
// Scan all policies
|
|
155
|
+
for (const [, policyXml] of policies) {
|
|
156
|
+
for (const dep of scanPolicyReferences(policyXml)) {
|
|
157
|
+
const key = `${dep.type}:${dep.name.toLowerCase()}`;
|
|
158
|
+
if (!seen.has(key)) {
|
|
159
|
+
seen.add(key);
|
|
160
|
+
dependencies.push({ type: dep.type, nameParts: [dep.name] });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Scan API version set references
|
|
165
|
+
for (const [, apiJson] of apis) {
|
|
166
|
+
const dep = scanApiVersionSetReference(apiJson);
|
|
167
|
+
if (dep) {
|
|
168
|
+
const key = `${dep.type}:${dep.name.toLowerCase()}`;
|
|
169
|
+
if (!seen.has(key)) {
|
|
170
|
+
seen.add(key);
|
|
171
|
+
dependencies.push({ type: dep.type, nameParts: [dep.name] });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return dependencies;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=transitive-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transitive-resolver.js","sourceRoot":"","sources":["../../src/services/transitive-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T027: Workspace-scoped extraction
|
|
3
|
+
* List workspaces, extract workspace-scoped resources under workspaces/{name}/
|
|
4
|
+
* using same resource-extractor with workspace context prefix.
|
|
5
|
+
*/
|
|
6
|
+
import { IApimClient } from '../clients/iapim-client.js';
|
|
7
|
+
import { IArtifactStore } from '../clients/iartifact-store.js';
|
|
8
|
+
import { ApimServiceContext } from '../models/types.js';
|
|
9
|
+
import { FilterConfig } from '../models/config.js';
|
|
10
|
+
/**
|
|
11
|
+
* Result of extracting a single workspace.
|
|
12
|
+
*/
|
|
13
|
+
export interface WorkspaceExtractionResult {
|
|
14
|
+
workspaceName: string;
|
|
15
|
+
resourceCount: number;
|
|
16
|
+
errorCount: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extract resources from all workspaces.
|
|
20
|
+
*
|
|
21
|
+
* Note: Workspace listing is not supported through the current IApimClient
|
|
22
|
+
* interface (ResourceType doesn't include Workspace). This function accepts
|
|
23
|
+
* workspace names from the filter config. If workspaceNames is not specified
|
|
24
|
+
* in the filter, workspace extraction is skipped.
|
|
25
|
+
*
|
|
26
|
+
* @param client - APIM REST client
|
|
27
|
+
* @param store - Artifact file store
|
|
28
|
+
* @param context - APIM service context
|
|
29
|
+
* @param outputDir - Output directory
|
|
30
|
+
* @param filter - Optional filter config (workspace names come from here)
|
|
31
|
+
* @returns Results per workspace
|
|
32
|
+
*/
|
|
33
|
+
export declare function extractWorkspaces(client: IApimClient, store: IArtifactStore, context: ApimServiceContext, outputDir: string, filter?: FilterConfig): Promise<WorkspaceExtractionResult[]>;
|
|
34
|
+
//# sourceMappingURL=workspace-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-extractor.d.ts","sourceRoot":"","sources":["../../src/services/workspace-extractor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAyBnD;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAqBtC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T027: Workspace-scoped extraction
|
|
3
|
+
* List workspaces, extract workspace-scoped resources under workspaces/{name}/
|
|
4
|
+
* using same resource-extractor with workspace context prefix.
|
|
5
|
+
*/
|
|
6
|
+
import { ResourceType } from '../models/resource-types.js';
|
|
7
|
+
import { extractResourceType } from './resource-extractor.js';
|
|
8
|
+
import { extractApiResources } from './api-extractor.js';
|
|
9
|
+
import { extractProductResources } from './product-extractor.js';
|
|
10
|
+
import { logger } from '../lib/logger.js';
|
|
11
|
+
/**
|
|
12
|
+
* Types that can exist at the workspace level.
|
|
13
|
+
* Not all APIM resource types support workspace scoping.
|
|
14
|
+
*/
|
|
15
|
+
const WORKSPACE_SUPPORTED_TYPES = [
|
|
16
|
+
ResourceType.NamedValue,
|
|
17
|
+
ResourceType.Tag,
|
|
18
|
+
ResourceType.Backend,
|
|
19
|
+
ResourceType.Logger,
|
|
20
|
+
ResourceType.Diagnostic,
|
|
21
|
+
ResourceType.PolicyFragment,
|
|
22
|
+
ResourceType.Product,
|
|
23
|
+
ResourceType.Api,
|
|
24
|
+
ResourceType.Subscription,
|
|
25
|
+
ResourceType.GlobalSchema,
|
|
26
|
+
ResourceType.Documentation,
|
|
27
|
+
ResourceType.Group,
|
|
28
|
+
];
|
|
29
|
+
/**
|
|
30
|
+
* Extract resources from all workspaces.
|
|
31
|
+
*
|
|
32
|
+
* Note: Workspace listing is not supported through the current IApimClient
|
|
33
|
+
* interface (ResourceType doesn't include Workspace). This function accepts
|
|
34
|
+
* workspace names from the filter config. If workspaceNames is not specified
|
|
35
|
+
* in the filter, workspace extraction is skipped.
|
|
36
|
+
*
|
|
37
|
+
* @param client - APIM REST client
|
|
38
|
+
* @param store - Artifact file store
|
|
39
|
+
* @param context - APIM service context
|
|
40
|
+
* @param outputDir - Output directory
|
|
41
|
+
* @param filter - Optional filter config (workspace names come from here)
|
|
42
|
+
* @returns Results per workspace
|
|
43
|
+
*/
|
|
44
|
+
export async function extractWorkspaces(client, store, context, outputDir, filter) {
|
|
45
|
+
const results = [];
|
|
46
|
+
// Workspace names must be explicitly provided via filter config
|
|
47
|
+
// since the IApimClient interface doesn't support listing workspaces
|
|
48
|
+
const workspaceNames = filter?.workspaceNames;
|
|
49
|
+
if (!workspaceNames || workspaceNames.length === 0) {
|
|
50
|
+
logger.debug('No workspace names specified in filter — skipping workspace extraction');
|
|
51
|
+
return results;
|
|
52
|
+
}
|
|
53
|
+
logger.info(`Extracting ${workspaceNames.length} workspace(s)...`);
|
|
54
|
+
for (const wsName of workspaceNames) {
|
|
55
|
+
const wsResult = await extractWorkspace(client, store, context, wsName, outputDir, filter);
|
|
56
|
+
results.push(wsResult);
|
|
57
|
+
}
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Extract all resources from a single workspace.
|
|
62
|
+
*/
|
|
63
|
+
async function extractWorkspace(client, store, context, workspaceName, outputDir, filter) {
|
|
64
|
+
logger.info(`Extracting workspace "${workspaceName}"...`);
|
|
65
|
+
let resourceCount = 0;
|
|
66
|
+
let errorCount = 0;
|
|
67
|
+
// Create workspace-scoped context
|
|
68
|
+
// Workspace resources are accessed via the same base URL but with /workspaces/{name} prefix
|
|
69
|
+
const wsContext = {
|
|
70
|
+
...context,
|
|
71
|
+
baseUrl: `${context.baseUrl}/workspaces/${encodeURIComponent(workspaceName)}`,
|
|
72
|
+
};
|
|
73
|
+
// Extract each supported resource type within the workspace
|
|
74
|
+
for (const type of WORKSPACE_SUPPORTED_TYPES) {
|
|
75
|
+
try {
|
|
76
|
+
const result = await extractResourceType(client, store, wsContext, type, outputDir, filter, undefined, workspaceName);
|
|
77
|
+
resourceCount += result.extracted.filter((r) => r.status === 'success').length;
|
|
78
|
+
errorCount += result.errorCount;
|
|
79
|
+
// Handle API-specific extraction for APIs in the workspace
|
|
80
|
+
if (type === ResourceType.Api) {
|
|
81
|
+
for (const api of result.extracted) {
|
|
82
|
+
if (api.status !== 'success')
|
|
83
|
+
continue;
|
|
84
|
+
try {
|
|
85
|
+
const apiResult = await extractApiResources(client, store, wsContext, api.descriptor, api.json, outputDir, filter, workspaceName);
|
|
86
|
+
resourceCount += apiResult.operations.length +
|
|
87
|
+
apiResult.tags.length +
|
|
88
|
+
apiResult.schemas.length;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
logger.warn(`Failed to extract API details for workspace "${workspaceName}": ${error.message}`);
|
|
92
|
+
errorCount++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Handle product-specific extraction for products in the workspace
|
|
97
|
+
if (type === ResourceType.Product) {
|
|
98
|
+
for (const product of result.extracted) {
|
|
99
|
+
if (product.status !== 'success')
|
|
100
|
+
continue;
|
|
101
|
+
try {
|
|
102
|
+
await extractProductResources(client, store, wsContext, product.descriptor, outputDir, filter, workspaceName);
|
|
103
|
+
resourceCount++;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
logger.warn(`Failed to extract product details for workspace "${workspaceName}": ${error.message}`);
|
|
107
|
+
errorCount++;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
logger.warn(`Failed to extract ${type} from workspace "${workspaceName}": ${error.message}`);
|
|
114
|
+
errorCount++;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
logger.info(`Workspace "${workspaceName}": extracted ${resourceCount} resources, ${errorCount} errors`);
|
|
118
|
+
return { workspaceName, resourceCount, errorCount };
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=workspace-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-extractor.js","sourceRoot":"","sources":["../../src/services/workspace-extractor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C;;;GAGG;AACH,MAAM,yBAAyB,GAAmB;IAChD,YAAY,CAAC,UAAU;IACvB,YAAY,CAAC,GAAG;IAChB,YAAY,CAAC,OAAO;IACpB,YAAY,CAAC,MAAM;IACnB,YAAY,CAAC,UAAU;IACvB,YAAY,CAAC,cAAc;IAC3B,YAAY,CAAC,OAAO;IACpB,YAAY,CAAC,GAAG;IAChB,YAAY,CAAC,YAAY;IACzB,YAAY,CAAC,YAAY;IACzB,YAAY,CAAC,aAAa;IAC1B,YAAY,CAAC,KAAK;CACnB,CAAC;AAWF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAmB,EACnB,KAAqB,EACrB,OAA2B,EAC3B,SAAiB,EACjB,MAAqB;IAErB,MAAM,OAAO,GAAgC,EAAE,CAAC;IAEhD,gEAAgE;IAChE,qEAAqE;IACrE,MAAM,cAAc,GAAG,MAAM,EAAE,cAAc,CAAC;IAC9C,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;QACvF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,cAAc,cAAc,CAAC,MAAM,kBAAkB,CAAC,CAAC;IAEnE,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CACrC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAClD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC7B,MAAmB,EACnB,KAAqB,EACrB,OAA2B,EAC3B,aAAqB,EACrB,SAAiB,EACjB,MAAqB;IAErB,MAAM,CAAC,IAAI,CAAC,yBAAyB,aAAa,MAAM,CAAC,CAAC;IAE1D,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,kCAAkC;IAClC,4FAA4F;IAC5F,MAAM,SAAS,GAAuB;QACpC,GAAG,OAAO;QACV,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,eAAe,kBAAkB,CAAC,aAAa,CAAC,EAAE;KAC9E,CAAC;IAEF,4DAA4D;IAC5D,KAAK,MAAM,IAAI,IAAI,yBAAyB,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,CACtC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAC9B,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,CAC5C,CAAC;YACF,aAAa,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;YAC/E,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;YAEhC,2DAA2D;YAC3D,IAAI,IAAI,KAAK,YAAY,CAAC,GAAG,EAAE,CAAC;gBAC9B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;oBACnC,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;wBAAE,SAAS;oBACvC,IAAI,CAAC;wBACH,MAAM,SAAS,GAAG,MAAM,mBAAmB,CACzC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,EAClD,SAAS,EAAE,MAAM,EAAE,aAAa,CACjC,CAAC;wBACF,aAAa,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM;4BAC1C,SAAS,CAAC,IAAI,CAAC,MAAM;4BACrB,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;oBAC7B,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,IAAI,CAAC,gDAAgD,aAAa,MAAO,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;wBAC3G,UAAU,EAAE,CAAC;oBACf,CAAC;gBACH,CAAC;YACH,CAAC;YAED,mEAAmE;YACnE,IAAI,IAAI,KAAK,YAAY,CAAC,OAAO,EAAE,CAAC;gBAClC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;oBACvC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;wBAAE,SAAS;oBAC3C,IAAI,CAAC;wBACH,MAAM,uBAAuB,CAC3B,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,EAC5C,SAAS,EAAE,MAAM,EAAE,aAAa,CACjC,CAAC;wBACF,aAAa,EAAE,CAAC;oBAClB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,IAAI,CAAC,oDAAoD,aAAa,MAAO,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;wBAC/G,UAAU,EAAE,CAAC;oBACf,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,oBAAoB,aAAa,MAAO,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YACxG,UAAU,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,cAAc,aAAa,gBAAgB,aAAa,eAAe,UAAU,SAAS,CAAC,CAAC;IAExG,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T045: Azure DevOps extract pipeline template
|
|
3
|
+
* Manual trigger with configuration choice and auto-PR creation
|
|
4
|
+
*/
|
|
5
|
+
export interface ExtractPipelineConfig {
|
|
6
|
+
artifactDir: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function generateExtractPipeline(config: ExtractPipelineConfig): string;
|
|
9
|
+
//# sourceMappingURL=extract-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-pipeline.d.ts","sourceRoot":"","sources":["../../../src/templates/azure-devops/extract-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAyF7E"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T045: Azure DevOps extract pipeline template
|
|
3
|
+
* Manual trigger with configuration choice and auto-PR creation
|
|
4
|
+
*/
|
|
5
|
+
export function generateExtractPipeline(config) {
|
|
6
|
+
return `# Azure DevOps Pipeline: Run APIM Extractor
|
|
7
|
+
|
|
8
|
+
trigger: none
|
|
9
|
+
|
|
10
|
+
parameters:
|
|
11
|
+
- name: CONFIGURATION_YAML_PATH
|
|
12
|
+
type: string
|
|
13
|
+
displayName: 'Choose whether to extract all APIs or use the extraction configuration file'
|
|
14
|
+
default: 'Extract All APIs'
|
|
15
|
+
values:
|
|
16
|
+
- 'Extract All APIs'
|
|
17
|
+
- 'configuration.extract.yaml'
|
|
18
|
+
- name: resourceGroup
|
|
19
|
+
type: string
|
|
20
|
+
displayName: 'Azure Resource Group'
|
|
21
|
+
default: $(APIM_RESOURCE_GROUP)
|
|
22
|
+
- name: serviceName
|
|
23
|
+
type: string
|
|
24
|
+
displayName: 'APIM Service Name'
|
|
25
|
+
default: $(APIM_SERVICE_NAME)
|
|
26
|
+
|
|
27
|
+
pool:
|
|
28
|
+
vmImage: 'ubuntu-latest'
|
|
29
|
+
|
|
30
|
+
variables:
|
|
31
|
+
- group: apim-common
|
|
32
|
+
|
|
33
|
+
steps:
|
|
34
|
+
- task: NodeTool@0
|
|
35
|
+
displayName: 'Setup Node.js'
|
|
36
|
+
inputs:
|
|
37
|
+
versionSpec: '22.x'
|
|
38
|
+
|
|
39
|
+
- script: npm ci
|
|
40
|
+
displayName: 'Install dependencies'
|
|
41
|
+
|
|
42
|
+
- task: AzureCLI@2
|
|
43
|
+
displayName: 'Run APIM Extract (All APIs)'
|
|
44
|
+
condition: eq('\${{ parameters.CONFIGURATION_YAML_PATH }}', 'Extract All APIs')
|
|
45
|
+
inputs:
|
|
46
|
+
azureSubscription: '$(AZURE_SERVICE_CONNECTION)'
|
|
47
|
+
scriptType: 'bash'
|
|
48
|
+
scriptLocation: 'inlineScript'
|
|
49
|
+
inlineScript: |
|
|
50
|
+
npx apiops extract \\
|
|
51
|
+
--resource-group \${{ parameters.resourceGroup }} \\
|
|
52
|
+
--service-name \${{ parameters.serviceName }} \\
|
|
53
|
+
--output ${config.artifactDir} \\
|
|
54
|
+
--subscription-id $(AZURE_SUBSCRIPTION_ID)
|
|
55
|
+
|
|
56
|
+
- task: AzureCLI@2
|
|
57
|
+
displayName: 'Run APIM Extract (With Configuration)'
|
|
58
|
+
condition: ne('\${{ parameters.CONFIGURATION_YAML_PATH }}', 'Extract All APIs')
|
|
59
|
+
inputs:
|
|
60
|
+
azureSubscription: '$(AZURE_SERVICE_CONNECTION)'
|
|
61
|
+
scriptType: 'bash'
|
|
62
|
+
scriptLocation: 'inlineScript'
|
|
63
|
+
inlineScript: |
|
|
64
|
+
npx apiops extract \\
|
|
65
|
+
--resource-group \${{ parameters.resourceGroup }} \\
|
|
66
|
+
--service-name \${{ parameters.serviceName }} \\
|
|
67
|
+
--output ${config.artifactDir} \\
|
|
68
|
+
--filter configuration.extract.yaml \\
|
|
69
|
+
--subscription-id $(AZURE_SUBSCRIPTION_ID)
|
|
70
|
+
|
|
71
|
+
- task: PublishPipelineArtifact@1
|
|
72
|
+
displayName: 'Publish artifacts'
|
|
73
|
+
inputs:
|
|
74
|
+
targetPath: ${config.artifactDir}
|
|
75
|
+
artifactName: apim-artifacts
|
|
76
|
+
|
|
77
|
+
- script: |
|
|
78
|
+
BRANCH_NAME="apim-extract-$(Build.BuildId)"
|
|
79
|
+
git config user.name "Azure DevOps"
|
|
80
|
+
git config user.email "azuredevops@microsoft.com"
|
|
81
|
+
git checkout -b "$BRANCH_NAME"
|
|
82
|
+
git add ${config.artifactDir}
|
|
83
|
+
if git diff --cached --quiet; then
|
|
84
|
+
echo "No changes to commit"
|
|
85
|
+
else
|
|
86
|
+
git commit -m "chore: update APIM artifacts from extract"
|
|
87
|
+
git push origin "$BRANCH_NAME"
|
|
88
|
+
echo "##vso[task.logissue type=warning]Branch '$BRANCH_NAME' pushed. Please create a pull request to merge the changes."
|
|
89
|
+
fi
|
|
90
|
+
displayName: 'Create branch with changes'
|
|
91
|
+
env:
|
|
92
|
+
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=extract-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-pipeline.js","sourceRoot":"","sources":["../../../src/templates/azure-devops/extract-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,UAAU,uBAAuB,CAAC,MAA6B;IACnE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA+CY,MAAM,CAAC,WAAW;;;;;;;;;;;;;;qBAclB,MAAM,CAAC,WAAW;;;;;;;oBAOnB,MAAM,CAAC,WAAW;;;;;;;;gBAQtB,MAAM,CAAC,WAAW;;;;;;;;;;;CAWjC,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T046: Azure DevOps publish pipeline template
|
|
3
|
+
* Multi-stage pipeline with commit ID choice, environment selection, and variable groups
|
|
4
|
+
*/
|
|
5
|
+
export interface PublishPipelineConfig {
|
|
6
|
+
artifactDir: string;
|
|
7
|
+
environments: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function generatePublishPipeline(config: PublishPipelineConfig): string;
|
|
10
|
+
//# sourceMappingURL=publish-pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-pipeline.d.ts","sourceRoot":"","sources":["../../../src/templates/azure-devops/publish-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAiG7E"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T046: Azure DevOps publish pipeline template
|
|
3
|
+
* Multi-stage pipeline with commit ID choice, environment selection, and variable groups
|
|
4
|
+
*/
|
|
5
|
+
export function generatePublishPipeline(config) {
|
|
6
|
+
const envValues = config.environments.map((env) => ` - '${env}'`).join('\n');
|
|
7
|
+
const stages = config.environments.map((env, idx) => {
|
|
8
|
+
const dependsOn = idx === 0 ? '' : ` dependsOn: Publish_${config.environments[idx - 1]}\n`;
|
|
9
|
+
return `${dependsOn}- stage: Publish_${env}
|
|
10
|
+
displayName: 'Publish to ${env}'
|
|
11
|
+
condition: or(eq('\${{ parameters.ENVIRONMENT }}', '${env}'), eq('\${{ parameters.ENVIRONMENT }}', 'all'))
|
|
12
|
+
variables:
|
|
13
|
+
- group: apim-${env}
|
|
14
|
+
jobs:
|
|
15
|
+
- deployment: Deploy
|
|
16
|
+
displayName: 'Deploy to ${env}'
|
|
17
|
+
environment: ${env}
|
|
18
|
+
pool:
|
|
19
|
+
vmImage: 'ubuntu-latest'
|
|
20
|
+
strategy:
|
|
21
|
+
runOnce:
|
|
22
|
+
deploy:
|
|
23
|
+
steps:
|
|
24
|
+
- checkout: self
|
|
25
|
+
fetchDepth: 2
|
|
26
|
+
|
|
27
|
+
- task: NodeTool@0
|
|
28
|
+
displayName: 'Setup Node.js'
|
|
29
|
+
inputs:
|
|
30
|
+
versionSpec: '22.x'
|
|
31
|
+
|
|
32
|
+
- script: npm ci
|
|
33
|
+
displayName: 'Install dependencies'
|
|
34
|
+
|
|
35
|
+
- task: AzureCLI@2
|
|
36
|
+
displayName: 'Publish to ${env} (incremental - last commit only)'
|
|
37
|
+
condition: ne('\${{ parameters.COMMIT_ID_CHOICE }}', 'publish-all-artifacts-in-repo')
|
|
38
|
+
inputs:
|
|
39
|
+
azureSubscription: '$(AZURE_SERVICE_CONNECTION_${env.toUpperCase()})'
|
|
40
|
+
scriptType: 'bash'
|
|
41
|
+
scriptLocation: 'inlineScript'
|
|
42
|
+
inlineScript: |
|
|
43
|
+
npx apiops publish \\
|
|
44
|
+
--resource-group $(APIM_RESOURCE_GROUP_${env.toUpperCase()}) \\
|
|
45
|
+
--service-name $(APIM_SERVICE_NAME_${env.toUpperCase()}) \\
|
|
46
|
+
--source ${config.artifactDir} \\
|
|
47
|
+
--override configuration.${env}.yaml \\
|
|
48
|
+
--commit-id $(Build.SourceVersion) \\
|
|
49
|
+
--subscription-id $(AZURE_SUBSCRIPTION_ID)
|
|
50
|
+
|
|
51
|
+
- task: AzureCLI@2
|
|
52
|
+
displayName: 'Publish to ${env} (all artifacts)'
|
|
53
|
+
condition: eq('\${{ parameters.COMMIT_ID_CHOICE }}', 'publish-all-artifacts-in-repo')
|
|
54
|
+
inputs:
|
|
55
|
+
azureSubscription: '$(AZURE_SERVICE_CONNECTION_${env.toUpperCase()})'
|
|
56
|
+
scriptType: 'bash'
|
|
57
|
+
scriptLocation: 'inlineScript'
|
|
58
|
+
inlineScript: |
|
|
59
|
+
npx apiops publish \\
|
|
60
|
+
--resource-group $(APIM_RESOURCE_GROUP_${env.toUpperCase()}) \\
|
|
61
|
+
--service-name $(APIM_SERVICE_NAME_${env.toUpperCase()}) \\
|
|
62
|
+
--source ${config.artifactDir} \\
|
|
63
|
+
--override configuration.${env}.yaml \\
|
|
64
|
+
--subscription-id $(AZURE_SUBSCRIPTION_ID)
|
|
65
|
+
`;
|
|
66
|
+
}).join('\n');
|
|
67
|
+
return `# Azure DevOps Pipeline: Run APIM Publisher
|
|
68
|
+
|
|
69
|
+
trigger:
|
|
70
|
+
branches:
|
|
71
|
+
include:
|
|
72
|
+
- main
|
|
73
|
+
paths:
|
|
74
|
+
include:
|
|
75
|
+
- '${config.artifactDir}/**'
|
|
76
|
+
- 'configuration.*.yaml'
|
|
77
|
+
|
|
78
|
+
pr: none
|
|
79
|
+
|
|
80
|
+
parameters:
|
|
81
|
+
- name: COMMIT_ID_CHOICE
|
|
82
|
+
type: string
|
|
83
|
+
displayName: 'Choose "publish-all-artifacts-in-repo" only when you want to force republishing all artifacts (e.g. after build failure). Otherwise stick with the default behavior of "publish-artifacts-in-last-commit"'
|
|
84
|
+
default: 'publish-artifacts-in-last-commit'
|
|
85
|
+
values:
|
|
86
|
+
- 'publish-artifacts-in-last-commit'
|
|
87
|
+
- 'publish-all-artifacts-in-repo'
|
|
88
|
+
- name: ENVIRONMENT
|
|
89
|
+
type: string
|
|
90
|
+
displayName: 'Choose which environment to publish to'
|
|
91
|
+
default: 'all'
|
|
92
|
+
values:
|
|
93
|
+
- 'all'
|
|
94
|
+
${envValues}
|
|
95
|
+
|
|
96
|
+
stages:
|
|
97
|
+
${stages}
|
|
98
|
+
`;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=publish-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-pipeline.js","sourceRoot":"","sources":["../../../src/templates/azure-devops/publish-pipeline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,UAAU,uBAAuB,CAAC,MAA6B;IACnE,MAAM,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAElF,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAClD,MAAM,SAAS,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,wBAAwB,MAAM,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC;QAE5F,OAAO,GAAG,SAAS,oBAAoB,GAAG;6BACjB,GAAG;wDACwB,GAAG;;oBAEvC,GAAG;;;gCAGS,GAAG;qBACd,GAAG;;;;;;;;;;;;;;;;;;;2CAmBmB,GAAG;;;mEAGqB,GAAG,CAAC,WAAW,EAAE;;;;;+DAKrB,GAAG,CAAC,WAAW,EAAE;2DACrB,GAAG,CAAC,WAAW,EAAE;iCAC3C,MAAM,CAAC,WAAW;iDACF,GAAG;;;;;2CAKT,GAAG;;;mEAGqB,GAAG,CAAC,WAAW,EAAE;;;;;+DAKrB,GAAG,CAAC,WAAW,EAAE;2DACrB,GAAG,CAAC,WAAW,EAAE;iCAC3C,MAAM,CAAC,WAAW;iDACF,GAAG;;CAEnD,CAAC;IACA,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;;;;;;;;WAQE,MAAM,CAAC,WAAW;;;;;;;;;;;;;;;;;;;EAmB3B,SAAS;;;EAGT,MAAM;CACP,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-config.d.ts","sourceRoot":"","sources":["../../../src/templates/configs/filter-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,oBAAoB,IAAI,MAAM,CA6C7C"}
|