You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,12 +13,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
13
14
14
### Fixed
15
15
16
+
- Non-skill integrators (agent, instruction, prompt, command, hook script-copy) silently adopt byte-identical pre-existing files so a degraded `deployed_files=[]` lockfile no longer permanently blocks installs gated by `required-packages-deployed`. (#1313)
17
+
-`apm audit` drift check now returns skip-with-info (`passed=True`) when the install cache is cold, instead of failing the audit; bare `apm audit` surfaces the skip reason on stderr so CI pipelines that have not yet run `apm install` are not incorrectly red-marked. (#1289)
18
+
-`extends: org` now correctly layers `dependencies.require` and `dependencies.deny` from the parent policy when the child omits the `dependencies:` block entirely; `None` signals "no opinion" (transparent) while `[]` signals explicit override. (#1290)
19
+
- CI self-check job now uses `setup-only: true` + `apm audit --ci --no-drift` so managed files are not overwritten by `apm install` before `content-integrity` runs; documented the audit-only CI pattern and the install-before-audit blind spot in the enterprise and CI/CD guides. (#1291)
16
20
- Pin `Path.home()` under unit tests via a session-scoped autouse conftest fixture, fixing 56 Windows runner failures on the new `windows-2025-vs2026` GitHub-hosted image where `USERPROFILE`/`HOMEDRIVE`+`HOMEPATH` are not seeded for pytest workers; also patch the `_check_and_notify_updates` import binding in the disabled-self-update test so it no longer races on the version-check cache. (#1270)
17
21
-`apm install` now works on macOS git 2.53.0 (Homebrew): bare-cache commands switch to `--git-dir` to satisfy the `safe.bareRepository=explicit` default; fetched SHAs are pinned as synthetic refs so `git clone --local --shared` no longer silently omits them. (#1268)
18
22
- Set the unit-test hermetic HOME at conftest import time so a single xdist worker on the `windows-2025-vs2026` runner can no longer race fixture setup and re-trigger the 53 `Path.home()` failures the session-scoped autouse fixture was supposed to prevent. (#1271)
19
23
- Override `Path.home()` itself in the root test conftest so the 46 remaining Windows `RuntimeError: Could not determine home directory` failures on xdist worker `gw2` cannot recur regardless of which conftest the worker imports first; per-test `monkeypatch.setenv("HOME", ...)` continues to work because the override consults env vars before falling back to the hermetic tmp dir. (#1272)
20
24
- Retry the `apm mcp search` and `apm mcp show` integration tests on the documented "Could not reach MCP registry" transient (with backoff and a final skip) so a brief `api.mcp.github.com` outage no longer red-marks the Windows integration job. (#1274)
21
25
- Also wrap `Path.expanduser()` in the root test conftest so the `windows-2025-vs2026` runner cannot raise `RuntimeError("Could not determine home directory.")` from `ntpath.expanduser` when production code (e.g. `install.package_resolution.user_scope_rejection_reason`) calls `Path("~/pkg").expanduser()`. Falls back to the hermetic tmp dir; assertions about `~/pkg` being absolute still hold. (#1276)
26
+
-`apm install` from marketplaces registered on `*.ghe.com` (GHE Cloud) hosts now routes auth at the registered enterprise host instead of silently defaulting to `github.com` and failing with 401; the marketplace resolver backfills the enterprise host onto the canonical so downstream `DependencyReference.parse` recovers it, and the resulting `apm.yml` entry records the correct enterprise `git:` URL instead of `https://github.com/...`. (#1292)
27
+
-`apm view --help` and the `view` row in `apm --help` now render in release binaries; PyInstaller's `optimize=2` was stripping `__doc__` from every Click command, and `view` was the only command that relied on its docstring instead of the explicit `help=` kwarg every other command defensively sets. Lowered the spec to `optimize=1` so asserts are still removed but docstrings survive, restoring Click's documented help-from-docstring fallback for all current and future commands. (#1298)
22
28
23
29
## [0.13.0] - 2026-05-11
24
30
@@ -33,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
33
39
-`apm install --frozen` performs a CI-safe, read-only install that fails fast (exit 1) when `apm.lock.yaml` is missing or out of sync with `apm.yml`; mutually exclusive with `--update`. (#1244)
34
40
- Zero-config private-package auth on github.com, `*.ghe.com`, and GHES when the `gh` CLI is logged in: APM uses `gh auth token --hostname <host>` before falling back to `git credential fill`. (#630)
35
41
- GitLab marketplace and install support: `gitlab.com` and self-managed instances (via `GITLAB_HOST` / `APM_GITLAB_HOSTS`) use GitLab REST v4 for `marketplace.json` and raw file reads; nested group paths are disambiguated via object-form `git:` + `path:`. (#1149)
42
+
-**Windows installer parity:** CI and GHES/air-gapped runners can **pin `VERSION`**, set **`GITHUB_URL`** (https only) and **`APM_REPO`**, and use **`APM_INSTALL_DIR`** like `install.sh`. Pinned installs verify the release **`.sha256`** unless **`APM_SKIP_CHECKSUM=1`** or **`-SkipChecksum`** (emergency only); `GITHUB_URL` drives GitHub.com (`api.github.com`) vs GHES (`{host}/api/v3`) for latest discovery. (#668)
36
43
- Virtual subdirectory and raw-file packages now resolve from self-hosted Git services (Gitea, Gogs) via raw URL with API v1/v3 fallback. (#587)
37
44
-`git: parent` lets packages in a git monorepo reference sibling paths via `{ git: parent, path: ... }` without repeating the full `git:` URL; the lockfile stores expanded host, repo, and resolved ref like every other virtual git dependency. (#1149)
38
45
-`shared/apm.md` gh-aw workflow exposes a `target:` import input (default `all`) so consumer workflows can ship slim, single-harness bundles. (#1184)
Copy file name to clipboardExpand all lines: docs/src/content/docs/enterprise/enforce-in-ci.md
+48Lines changed: 48 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -77,6 +77,54 @@ jobs:
77
77
Make this job a required status check via
78
78
[GitHub Rulesets](../github-rulesets/) and a violating PR cannot merge.
79
79
80
+
## Audit-only CI pattern
81
+
82
+
The default `microsoft/apm-action@v1` runs `apm install` before any
83
+
subsequent steps. That is the right default for most workflows: it ensures
84
+
the lockfile and deployed files are present before the audit reads them.
85
+
86
+
However, `apm install` overwrites every managed file with a fresh copy
87
+
before `apm audit --ci` runs. If a managed file was modified on disk after
88
+
the last install -- its bytes changed without updating the lockfile hash --
89
+
the install step silently restores the clean copy. The `content-integrity`
90
+
check then compares the freshly restored file against a hash that matches,
91
+
and the tampering goes undetected.
92
+
93
+
To detect post-install file modification, run the action in setup-only mode
94
+
so it only adds the CLI to `PATH` without touching deployed files:
95
+
96
+
```yaml
97
+
jobs:
98
+
audit:
99
+
runs-on: ubuntu-latest
100
+
permissions:
101
+
contents: read
102
+
steps:
103
+
- uses: actions/checkout@v4
104
+
- uses: microsoft/apm-action@v1
105
+
with:
106
+
setup-only: true # CLI only; does not run apm install
107
+
- run: apm audit --ci --no-drift
108
+
env:
109
+
GITHUB_APM_PAT: ${{ secrets.APM_PAT }}
110
+
```
111
+
112
+
`setup-only: true` leaves every deployed file exactly as checked out.
113
+
`--no-drift`skips the install-replay check because no warm cache exists;
114
+
the `content-integrity` check still verifies that every deployed file's
115
+
SHA-256 hash matches the `deployed_file_hashes` recorded in `apm.lock.yaml`.
116
+
Any file whose bytes were changed after the last install fails this check.
117
+
118
+
The two patterns serve different goals:
119
+
120
+
| Pattern | Use when |
121
+
|---|---|
122
+
| Full install then audit | Catching developers who skipped `apm install` after editing `apm.yml`; ensuring deployed files are present on a fresh runner |
123
+
| Audit-only (`setup-only: true`) | Detecting modification of deployed files after install; committed files and lockfile are the ground truth |
124
+
125
+
Both patterns enforce policy and the eight baseline lockfile checks. The
126
+
difference is only in whether content-integrity can see tampered bytes.
127
+
80
128
## Recipe: SARIF for GitHub Code Scanning
81
129
82
130
Emit SARIF and upload it so each violation appears inline on the PR
Copy file name to clipboardExpand all lines: docs/src/content/docs/getting-started/installation.md
+55-8Lines changed: 55 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,6 +11,8 @@ sidebar:
11
11
-[git](https://git-scm.com/) for dependency management
12
12
- Python 3.10+ (only for pip or from-source installs)
13
13
14
+
On **Windows ARM64**, the one-line installer currently downloads the **x86_64** ZIP (same as the GitHub Release asset); it runs via emulation. Native ARM64 Windows binaries are not selected yet.
15
+
14
16
## Quick install (recommended)
15
17
16
18
**macOS / Linux:**
@@ -29,7 +31,7 @@ The installer automatically detects your platform (macOS/Linux/Windows, Intel/AR
29
31
30
32
### Installer options
31
33
32
-
The Unix installer supports environment variables for custom environments:
34
+
**macOS / Linux (`install.sh`):**
33
35
34
36
```bash
35
37
# Install a specific version
@@ -42,15 +44,60 @@ curl -sSL https://aka.ms/apm-unix | APM_INSTALL_DIR=$HOME/.local/bin sh
42
44
GITHUB_URL=https://github.corp.com VERSION=v1.2.3 sh install.sh
43
45
```
44
46
47
+
**Windows (`install.ps1` in PowerShell):**
48
+
49
+
Air-gapped hosts should **save `install.ps1` locally** (the `irm` one-liner needs reachability to the script URL).
50
+
51
+
```powershell
52
+
# Pin a version (skips GitHub API - required for many air-gapped / GHES setups)
53
+
# Pinned installs verify SHA256 from the matching .sha256 unless you set:
# Fork, enterprise host, or internal mirror (GITHUB_URL must be https://)
64
+
$env:GITHUB_URL = "https://github.corp.com"
65
+
$env:APM_REPO = "my-org/apm"
66
+
$env:VERSION = "v1.2.3"
67
+
irm https://aka.ms/apm-windows | iex
68
+
```
69
+
70
+
**GitHub Actions (`windows-latest`):**
71
+
72
+
```yaml
73
+
jobs:
74
+
install-apm:
75
+
runs-on: windows-latest
76
+
steps:
77
+
- name: Install APM (pinned, CI-safe)
78
+
shell: pwsh
79
+
env:
80
+
VERSION: v0.13.0
81
+
# For GHES or a mirror, set GITHUB_URL (https only) and APM_REPO as needed.
82
+
run: |
83
+
irm https://aka.ms/apm-windows | iex
84
+
apm --version
85
+
- uses: actions/checkout@v4
86
+
- run: apm install --frozen
87
+
```
88
+
45
89
| Variable | Default | Description |
46
90
|----------|---------|-------------|
47
-
|`APM_INSTALL_DIR`|`/usr/local/bin`| Directory for the `apm` symlink |
48
-
|`APM_LIB_DIR`|`$(dirname APM_INSTALL_DIR)/lib/apm`| Directory for the full binary bundle |
49
-
|`GITHUB_URL`|`https://github.com`| Base URL for downloads (mirrors, GHE) |
50
-
|`APM_REPO`|`microsoft/apm`| GitHub repository |
51
-
|`VERSION`|*(latest)*| Pin a specific release (skips GitHub API) |
52
-
53
-
> **Note:** When using `GITHUB_URL` for a GitHub Enterprise or air-gapped mirror, set `VERSION` as well. The GitHub API call for latest-release discovery still targets `api.github.com`; `VERSION` bypasses it entirely.
91
+
| `APM_INSTALL_DIR` | `/usr/local/bin` (Unix) / `%LOCALAPPDATA%\Programs\apm\bin` (Windows) | Directory for the `apm` symlink / `apm.cmd` shim |
92
+
| `APM_LIB_DIR` | `$(dirname APM_INSTALL_DIR)/lib/apm` | *(Unix only)* Directory for the full binary bundle |
93
+
| `GITHUB_URL` | `https://github.com` | Base GitHub URL (asset downloads **and** API host: `api.github.com`on github.com, `{GITHUB_URL}/api/v3` on GHES). Must be `https://`. |
94
+
| `APM_REPO` | `microsoft/apm` | Repository as `owner/name` |
95
+
| `VERSION` | *(latest)* | Pin a release tag (skips the **releases/latest** HTTP API). Must look like `v1.2.3` or `1.2.3`. |
96
+
| `APM_SKIP_CHECKSUM` | *(unset)* | Windows only: set to `1` to skip `.sha256` verification on **pinned** installs (emergency only). |
97
+
98
+
> **Note - Unix (`install.sh`):** Latest-release discovery still calls `https://api.github.com/repos/.../releases/latest` unless `VERSION` is set. For GHES or mirrors with no access to `api.github.com`, pin `VERSION` so the script never hits that endpoint.
99
+
>
100
+
> **Note - Windows (`install.ps1`):** The **releases/latest** URL is derived from `GITHUB_URL`: `https://api.github.com` for GitHub.com, or `{GITHUB_URL}/api/v3` for GitHub Enterprise Server. Air-gapped runners should still set `VERSION` so the installer does not need the API at all. When `VERSION` is pinned, the release **`.sha256`** file is required unless you set **`APM_SKIP_CHECKSUM=1`** (emergency only).
0 commit comments