Skip to content

Commit 523ed55

Browse files
committed
updating instructions for 'npm ci --offline'
1 parent c8937cc commit 523ed55

1 file changed

Lines changed: 77 additions & 62 deletions

File tree

docs/walkthrough/air-gapped-azure-devops-offline-tarball.md

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,14 @@ flowchart LR
4040
| Requirement | Details |
4141
|-------------|---------|
4242
| **Connected workstation** | A machine with internet access to download the CLI and its dependencies |
43-
| **Node.js 22.x** | Installed on both the workstation and the agent (includes npm) |
4443
| **[Self-hosted Azure Pipelines agent](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops#self-hosted-agents)** | Registered in your agent pool, running in the air-gapped network |
44+
| **Node.js 22.x** | Installed on both the workstation and the Azure Pipelines agent (includes npm). Download of Node.js available at <https://nodejs.org/download>. |
4545
| **Azure connectivity from agent** | The agent must reach your APIM instance's ARM endpoint (network-level only) |
4646
| **File transfer mechanism** | A way to copy the npm cache directory into the air-gapped network |
4747

48-
> **On-premises Azure DevOps:** If you run [Azure DevOps Server](https://learn.microsoft.com/en-us/azure/devops/server/install/get-started?view=azure-devops-2022), the same approach applies.
49-
5048
---
5149

52-
## Step 1 — Pack the CLI
50+
### 1. Pack the CLI
5351

5452
On the connected workstation:
5553

@@ -59,26 +57,19 @@ npm pack @peterhauge/apiops-cli
5957

6058
This produces `peterhauge-apiops-cli-<version>.tgz` in the current directory.
6159

62-
Commit the tarball into your repository (e.g., under `.apiops/`) so the pipeline can reference it by path:
63-
64-
```bash
65-
mkdir -p .apiops
66-
mv peterhauge-apiops-cli-*.tgz .apiops/
67-
git add .apiops/peterhauge-apiops-cli-*.tgz
68-
```
69-
7060
---
7161

72-
## Step 2 — Initialize the Repository
62+
## 2. Add `apiops` related files to repository
63+
64+
### 2.1 Initialize your repository
7365

7466
Pass `--cli-package` so the generated `package.json` references the local tarball instead of the public registry:
7567

7668
```bash
7769
apiops init \
7870
--ci azure-devops \
7971
--environments dev,prod \
80-
--cli-package ./.apiops/peterhauge-apiops-cli-<version>.tgz \
81-
--non-interactive
72+
--cli-package <path-to-tarball>/peterhauge-apiops-cli-<version>.tgz
8273
```
8374

8475
This command generates:
@@ -90,9 +81,11 @@ This command generates:
9081
| `pipelines/run-publisher.yaml` | Publish pipeline |
9182
| `configuration.*.yaml` | Override templates |
9283

84+
Follow the remaining instructions listed in created `IDENTITY-SETUP-AZDO.md` or run `/apiops-setup-identity` prompt. This creates the necessary variable groups and and service connections.
85+
9386
---
9487

95-
## Step 3 — Generate the Lock File and Pre-Stage the npm Cache
88+
### 2.2 Generate the Lock File and Pre-Stage the npm Cache
9689

9790
On the **connected workstation**, run:
9891

@@ -101,91 +94,116 @@ npm install # creates package-lock.json
10194
npm ci # populates ~/.npm/_cacache/ with every package the lock file references
10295
```
10396

104-
Commit `package-lock.json` to the repository. The command `npm ci --offline` requires it.
97+
> The command `npm ci --offline` requires a package lock file.
10598
106-
Then transfer the npm cache to the agent:
99+
### 2.3 Modify Pipelines for Air-Gapped Operation
107100

108-
```bash
109-
# On the workstation
110-
tar -czf npm-cacache.tar.gz -C ~/.npm _cacache
101+
The generated pipelines (`pipelines/run-extractor.yaml` and `pipelines/run-publisher.yaml`) need the following edits:
111102

112-
# Transfer npm-cacache.tar.gz into the air-gapped network, then on the agent:
113-
mkdir -p ~/.npm
114-
tar -xzf npm-cacache.tar.gz -C ~/.npm
115-
```
103+
| Edit | What to Change |
104+
|------|----------------|
105+
| 1. **Agent pool** | Update [pool YAML schema](https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/pool?view=azure-pipelines). Replace `pool: vmImage: ubuntu-latest` with self-hosted agent pool (e.g. `pool: name: air-gapped-pool`). <br> (See next step [Configure the Azure DevOps Self-Hosted Agent](#3-configure-the-azure-devops-self-hosted-agent) for setup details.) |
106+
| 2. **Remove NodeTool task** | Delete the `NodeTool@0` step (Node.js is pre-installed on the agent).<br> No `npmAuthenticate@0` task is needed for offline mode. |
107+
| 3. **Use offline `npm ci`** | Change `npm ci` to `npm ci --offline`. |
116108

117-
> Repeat this cache transfer every time dependencies change (CLI upgrade, new package, etc.).
109+
### 2.4 Commit `apiops` related files
118110

111+
For the offline-tarball workflow, commit the files that make the pipeline fully reproducible without npm registry access:
112+
113+
| File Name | Description |
114+
|-----------|-------------|
115+
| `.apiops/peterhauge-apiops-cli-<version>.tgz` | CLI package consumed by the pipelines. |
116+
| `package.json` | Contains the `file:` dependency pointing to the tarball. |
117+
| `package-lock.json` | Required for deterministic offline installs with `npm ci --offline`. |
118+
| `pipelines/run-extractor.yaml` | Azure DevOps extract pipeline definition. |
119+
| `pipelines/run-publisher.yaml` | Azure DevOps publish pipeline definition. |
120+
| `configuration.*.yaml` | Generated environment override templates. |
121+
122+
```bash
123+
git add \
124+
.apiops/peterhauge-apiops-cli-*.tgz \
125+
package.json \
126+
package-lock.json \
127+
pipelines/run-extractor.yaml \
128+
pipelines/run-publisher.yaml \
129+
configuration.*.yaml
130+
git commit -m "chore: commit offline-tarball apiops bootstrap files"
131+
git push
132+
```
119133
---
120134

121-
## Step 4 — Configure the Self-Hosted Agent
135+
## 3. Configure the Azure DevOps Self-Hosted Agent
122136

123137
Install and register the agent in the air-gapped network per the [self-hosted agent documentation](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/linux-agent?view=azure-devops).
124138

139+
### 3.1 Verify rerequisites
140+
125141
Verify the following:
126142

127143
1. **Node.js 22.x** is installed and on `PATH`
128-
2. **npm cache is pre-staged** at the agent service account's `~/.npm/_cacache/` (see Step 3)
129144
3. **Network access to Azure ARM** — the agent must reach `management.azure.com` (or [sovereign cloud equivalent](https://learn.microsoft.com/en-us/azure/developer/identity/national-cloud))
130145
4. **Network access to Azure DevOps** — the agent must reach your Azure DevOps org for job dispatch
131146
5. **Git** is installed (required by the `checkout` step)
132147

133148
> **Agent pool:** Add your air-gapped agents to a [dedicated agent pool](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/pools-queues?view=azure-devops) (e.g., `air-gapped-pool`) so pipelines target them explicitly.
134149
135-
---
136-
137-
## Step 5 — Modify Pipelines for Air-Gapped Operation
138150

139-
The generated pipelines (`pipelines/run-extractor.yaml` and `pipelines/run-publisher.yaml`) need three edits:
140-
141-
| Edit | What to Change |
142-
|------|----------------|
143-
| **Agent pool** | Replace `pool: vmImage: ubuntu-latest` with `pool: name: air-gapped-pool` ([pool YAML schema](https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/pool?view=azure-pipelines)) |
144-
| **Remove NodeTool task** | Delete the `NodeTool@0` step (Node.js is pre-installed on the agent) |
145-
| **Use offline `npm ci`** | Change `npm ci` to `npm ci --offline` so npm resolves entirely from the pre-staged cache |
151+
### 3.2 Transfer npm cache files for offline use
146152

147-
No `npmAuthenticate@0` task is needed — there is no registry to authenticate against. The `--offline` flag makes npm fail fast if any package is missing from the cache instead of attempting a network call.
153+
The command `npm ci --offline` requires package-lock.json and npm cache to be pre-populated.
148154

149-
> **Azure authentication:** The `AzureCLI@2` task handles Azure authentication via the service connection. The service connection injects tokens for `DefaultAzureCredential`.
150-
151-
---
152-
153-
## Step 6 — Configure Variable Groups and Service Connections
154-
155-
Follow the standard [Azure DevOps integration guide](../ci-cd/azure-devops.md#variable-groups-configuration) to set up:
155+
Then transfer the npm cache to the agent:
156156

157-
1. **Variable group `apim-common`** — variables shared across all environments (e.g., subscription ID, tenant ID, common tags)
158-
2. **Variable groups `apim-dev`, `apim-prod`** — environment-specific variables (e.g., APIM instance name, resource group) that override values from `apim-common`
159-
3. **Service connections** — Azure Resource Manager connections scoped to your APIM instances; they can be referenced from either variable group
157+
```bash
158+
# On the workstation
159+
tar -czf npm-cacache.tar.gz -C ~/.npm _cacache
160160

161-
These are configured in Azure DevOps and are injected at pipeline runtime.
161+
# Transfer npm-cacache.tar.gz into the air-gapped network, then on the agent:
162+
mkdir -p ~/.npm
163+
tar -xzf npm-cacache.tar.gz -C ~/.npm
164+
```
162165

163-
---
166+
## 4 - Finish `apiops init` for pipeline
164167

165-
## Step 7 — Commit and Validate
168+
If not already done, while on the air-gapped network, follow the remaining instructions listed in created `IDENTITY-SETUP-AZDO.md`. This creates the necessary variable groups and and service connections.
166169

167-
```bash
168-
git add .
169-
git commit -m "feat: air-gapped apiops setup with offline tarball"
170-
git push
171-
```
170+
## 5 — Commit and Validate
172171

173172
Trigger the extract pipeline manually from **Pipelines → Run pipeline** and verify:
174173

175174
1. `npm ci --offline` completes with no network calls
176175
2. `apiops extract` authenticates via the service connection and runs successfully
177176

178-
> **✅ Setup complete.** Your air-gapped apiops pipelines are now operational. The remaining sections cover ongoing maintenance and reference material — read them as needed.
177+
> **✅ Setup complete.** Your air-gapped apiops pipelines are now operational. The remaining sections cover ongoing maintenance and troubleshooting.
179178
180179
---
181180

182181
## Upgrading the CLI Version
183182

184183
1. On a connected workstation, run `npm pack @peterhauge/apiops-cli` for the new version
185184
2. Replace `.apiops/peterhauge-apiops-cli-*.tgz` with the new tarball and update the `file:` path in `package.json`
186-
3. Regenerate `package-lock.json` (`npm install`)
185+
3. Regenerate `package-lock.json`
186+
```bash
187+
npm install
188+
```
187189
4. Re-populate and re-transfer the npm cache (`npm ci` on the workstation, then copy `~/.npm/_cacache/`)
190+
```bash
191+
# On the workstation
192+
tar -czf npm-cacache.tar.gz -C ~/.npm _cacache
193+
194+
# Transfer npm-cacache.tar.gz into the air-gapped network, then on the agent:
195+
mkdir -p ~/.npm
196+
tar -xzf npm-cacache.tar.gz -C ~/.npm
197+
```
188198
5. Commit the tarball and updated lock file
199+
```bash
200+
git add \
201+
.apiops/peterhauge-apiops-cli-*.tgz \
202+
package.json \
203+
package-lock.json \
204+
git commit -m "chore: commit updated offline-tarball apiops bootstrap files"
205+
git push
206+
```
189207

190208
---
191209

@@ -207,9 +225,6 @@ Trigger the extract pipeline manually from **Pipelines → Run pipeline** and ve
207225
208226
- [Local npm Registry walkthrough](air-gapped-azure-devops-local-registry.md) — recommended when an internal feed is available
209227
- [apiops init reference](../commands/init.md) — full `--cli-package` documentation
210-
- [Azure DevOps integration](../ci-cd/azure-devops.md) — standard (connected) setup
211-
- [Authentication guide](../guides/authentication.md) — service principal and managed identity options
212-
- [Air-gapped setup: GitHub Actions](air-gapped-github-actions.md)
213228
- [Self-hosted agents](https://learn.microsoft.com/en-us/azure/devops/pipelines/agents/agents?view=azure-devops#self-hosted-agents) — agent installation and configuration
214229
- [Azure DevOps Server](https://learn.microsoft.com/en-us/azure/devops/server/install/get-started?view=azure-devops-2022) — on-premises installation
215230
- [National cloud endpoints](https://learn.microsoft.com/en-us/azure/developer/identity/national-cloud) — sovereign cloud identity configuration

0 commit comments

Comments
 (0)