diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5089175..5a08db5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,8 +13,8 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v7 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 with: python-version: "3.12" - run: uv sync --extra dev @@ -24,8 +24,8 @@ jobs: version-sync: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.12" - name: Verify server.json matches pyproject.toml @@ -34,7 +34,7 @@ jobs: validate-server-json: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/install-mcp-publisher - name: Validate server.json against registry schema run: ./mcp-publisher validate server.json @@ -42,8 +42,8 @@ jobs: typecheck: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v7 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 with: python-version: "3.12" - run: uv sync --extra dev @@ -56,13 +56,13 @@ jobs: matrix: python-version: ["3.11", "3.12", "3.13"] steps: - - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v7 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 with: python-version: ${{ matrix.python-version }} - run: uv sync --extra dev - run: uv run pytest --cov=mcp_synology --cov-report=xml - - uses: codecov/codecov-action@v6 + - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 if: matrix.python-version == '3.12' with: files: coverage.xml diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3b1f509..f21d854 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,9 +12,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: astral-sh/setup-uv@v7 + - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 with: python-version: "3.12" @@ -27,7 +27,7 @@ jobs: run: uv build - name: Upload distributions - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: dist path: dist/ @@ -47,7 +47,7 @@ jobs: # or publisher version changes between merge and tag-push. runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/install-mcp-publisher - name: Validate server.json against registry schema run: ./mcp-publisher validate server.json @@ -60,13 +60,13 @@ jobs: id-token: write steps: - name: Download distributions - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: dist path: dist/ - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 publish-registry: # Publish (or update) the server entry in the official MCP registry. @@ -78,7 +78,7 @@ jobs: id-token: write contents: read steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: ./.github/actions/install-mcp-publisher @@ -120,7 +120,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 diff --git a/.github/workflows/test-publish.yml b/.github/workflows/test-publish.yml index 220114b..5904b4d 100644 --- a/.github/workflows/test-publish.yml +++ b/.github/workflows/test-publish.yml @@ -10,9 +10,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: astral-sh/setup-uv@v7 + - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 with: python-version: "3.12" @@ -25,7 +25,7 @@ jobs: run: uv build - name: Upload distributions - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: dist path: dist/ @@ -38,12 +38,12 @@ jobs: id-token: write steps: - name: Download distributions - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: dist path: dist/ - name: Publish to TestPyPI - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 with: repository-url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/vdsm.yml b/.github/workflows/vdsm.yml index cb35046..f0c6040 100644 --- a/.github/workflows/vdsm.yml +++ b/.github/workflows/vdsm.yml @@ -27,7 +27,7 @@ jobs: continue-on-error: true timeout-minutes: 30 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Verify /dev/kvm is available run: | @@ -35,7 +35,7 @@ jobs: sudo chmod 666 /dev/kvm echo "KVM available" - - uses: astral-sh/setup-uv@v7 + - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 with: python-version: "3.12" @@ -54,7 +54,7 @@ jobs: # cache key manually or add the manifest to hashFiles. - name: Restore golden image cache id: cache-golden - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: | .vdsm/golden/dsm-${{ env.DSM_VERSION }}.tar.gz @@ -75,7 +75,7 @@ jobs: - name: Upload logs on failure if: failure() - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: vdsm-failure-logs path: | diff --git a/CHANGELOG.md b/CHANGELOG.md index e7b1e1b..0b254b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ ### Changed +- **Pin third-party GitHub Actions to commit SHAs** (#94) — closes #46. Every external action in `.github/workflows/*.yml` was previously pinned to a major-version tag (`actions/checkout@v6`, `astral-sh/setup-uv@v7`, etc.) — and `pypa/gh-action-pypi-publish@release/v1` was even pinned to a *branch* ref, which can move under us. A minor release within a major can introduce security or behavior regressions without detection on a tag-only pin. Now every third-party `uses:` line carries an immutable 40-char commit SHA with a trailing `# v` comment for human readability (the GitHub-recommended supply-chain pattern). Eight actions pinned across `ci.yml`, `publish.yml`, `test-publish.yml`, `vdsm.yml`: `actions/checkout` v6.0.2, `astral-sh/setup-uv` v7.6.0, `actions/setup-python` v6.2.0, `actions/upload-artifact` v7.0.1, `actions/download-artifact` v8.0.1, `actions/cache` v5.0.5, `codecov/codecov-action` v6.0.0, `pypa/gh-action-pypi-publish` v1.14.0. Local composite actions under `./.github/actions/*` are deliberately not pinned (in-repo, reviewed on merge — pinning them would produce stale-SHA noise on every internal change). `dependabot-changelog.yml` was already SHA-pinned (PR #60 work) and serves as the template the rest of the workflows now match. Dependabot's existing `github-actions` ecosystem in `.github/dependabot.yml` will propose SHA bump PRs weekly so the pins stay fresh. + - **Restructure debug-logging docs by use case in CLAUDE.md** (#91) — closes #43. The "three ways to enable debug" bullet under `## Key Conventions → Logging` framed activation by *mechanism* (`-v` flag, env var, config) and only acknowledged in a second-bullet parenthetical that `serve` doesn't accept the flag — readers skimmed and walked away thinking they could pass `-v` to `serve`. Bullet is now reframed by *subcommand*: for `serve` (Claude Desktop, no interactive flag) → env var or config; for `setup` / `check` (interactive CLI) → `-v`/`--verbose` or either of the above. `README.md`'s parallel section was already correctly scoped (`--verbose flag on setup/check` + `env var, works for all commands`) — no change needed there. `docs/credentials.md` doesn't reference debug logging. - **Document the full set of v2-pinned DSM APIs in CLAUDE.md** (#90) — closes #42. The "Version pinning" bullet under `## Key Conventions → DSM API Client` previously named only CopyMove, Delete, and Search as v2-pinned. Audit of `src/` (`grep -rn "max_version=2\|min(.*max_version, 2)"`) found two additional pins that the convention bullet didn't mention: `SYNO.FileStation.Upload` (`core/client.py::upload_file`, line 354 — pinned because Upload is a multipart POST not routed through `request()`, and v3 advertises a JSON body the multipart code can't speak) and `SYNO.FileStation.List getinfo` (`modules/filestation/metadata.py`, added by PR #77 to dodge the v3 multipath quirk that surfaced as #68). Bullet now lists all five with file pointers and the rationale ("removing any of these pins reintroduces silent failures on DSM 7.x"), so a future refactor can't innocently strip a pin and rediscover the bug.