Repository navigation
Description
Command that triggered the bug
apiops extract
Summary
During a single extract run, API revisions are written by two code paths:
- The top-level API list (
GET /apis) returns the current revision (under the base API
name) and every non-current revision (as;rev=N). Each of these is extracted in
full (spec, operations, schemas). This path is correct. extractApiRevisionsadditionally walksGET /apis/{id}/revisionsand writes an
apiInformation.json-only folder for every revision except the one literally
numbered1.
Because path 2 skips only the revision hard-coded as '1' (assuming revision 1 is always
the current/main API), an API whose current revision is not 1 (e.g. 2) gets a
redundant, incomplete folder: the current revision is re-emitted as a ;rev=2 folder that
contains only apiInformation.json — a thin duplicate of the main API folder.
Affected component
- Package:
@azure-tools/apiops-cli(v1.0.0) - File:
src/services/api-extractor.ts - Function:
extractApiRevisions
Root cause
In extractApiRevisions the loop skips only the revision literally numbered 1, on the
assumption that revision 1 is the main API:
const revNumber = revision.apiRevision ?? revision.revisionNumber;
if (!revNumber || revNumber === '1') {
// Skip revision 1 — it's the main API
continue;
}
...
const revJson = await client.getResource(context, descriptor); // API entity only
await store.writeResource(outputDir, descriptor, revJson); // writes ONLY apiInformation.jsonWhen the current revision is not 1, the === '1' guard skips the wrong revision:
- The current revision (e.g.
2) does not match the guard, soextractApiRevisions
re-writes it as a;rev=2folder — but this path only persists the API entity
(apiInformation.json), not children (spec/operations/schemas). The result is a thin
duplicate of the main API folder. - Revision
1(matched by the guard) is skipped by this path, but that is harmless here
because non-current revisions are already extracted in full by the top-level/apis
list path.
So the main folder and the full non-current revision folders are correct; the only defect is
the redundant, apiInformation.json-only folder emitted for the current revision.
Steps to reproduce
- In APIM, take an API with multiple revisions where the current revision is not
1
(e.g. create revision2and make it current). - Run
apiops extractagainst that service. - Inspect the output for that API.
Expected behavior
- The current revision is written once, as the main API folder, with full content.
- Each non-current revision (including revision
1when it is not current) is written
as a;rev=Nfolder. - No
;rev=Nfolder is created for the current revision.
Actual behavior
Example for an API named my-api (current revision = 2, all produced in one extract run):
apis/
my-api/ # rev 2 (current) — full: spec + operations + schemas (via /apis list)
my-api;rev=1/ # rev 1 (non-current) — full: spec + operations + schemas (via /apis list)
my-api;rev=2/ # rev 2 again — ONLY apiInformation.json (redundant thin duplicate)
- The current revision (
2) is duplicated as a thin;rev=2folder that has no children.
Downstream impact
publishpicks up the redundant;rev=2folder and attempts to re-create the current
revision, causing confusion and potential concurrency conflicts on large APIs.- The extra
apiInformation.json-only folder is misleading and pollutes the artifacts /
diffs for every API whose current revision is not1.
Suggested fix
Skip the current revision (via isCurrent === true) instead of the hard-coded revision
number 1. This correctly excludes whichever revision is current and extracts all others as
;rev=N:
const isCurrent = revision.isCurrent === true; // from revision metadata
if (isCurrent) {
// Current revision is represented by the main API folder — skip here.
continue;
}Additionally, consider whether extractApiRevisions is needed at all: non-current revisions
are already extracted in full via the top-level /apis list, so this path may be entirely
redundant (and only ever produces incomplete, apiInformation.json-only folders).
Environment
@azure-tools/apiops-cliv1.0.0- Command:
extract
apiops CLI version
v1.0.0
Environment details
@azure-tools/apiops-cliv1.0.0- Command:
extract
CI/CD environment
None
Is this bug blocking you?
None
Activity
fix: revision delete/create conflicts, in-use fragment skip, auth set…