diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 2efb3f3b78..a3e814572c 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -77,9 +77,10 @@ jobs: # Get-MpPreference -notcontains check matches the stored form exactly. # Every Add-MpPreference call uses -ErrorAction Stop, and a final # Get-MpPreference verification throws if any exclusion did not register - # so the step fails loudly instead of degrading silently. The list of - # effective exclusions is also echoed to the log so future investigations - # of Windows lane variance can see exactly which paths were covered. + # so the step fails loudly instead of degrading silently. A reason-coded + # audit table of effective exclusions is emitted to both the log and job + # summary so future investigations can see exactly which paths were + # covered and why each path was required. # テストスイートが大量に作る一時ファイル(temp project / SQLite DB / # .cdidx / 合成ソース)を Windows Defender が都度スキャンする影響で # Windows lane だけ極端に遅くなる(issue #394)。build/test 前に @@ -95,42 +96,93 @@ jobs: # Get-MpPreference -notcontains の照合を保存形式と完全一致させる。 # 各呼び出しを -ErrorAction Stop で明示失敗させ、最後に Get-MpPreference # で登録を検証し、silent degradation を起こさないようにする。最終的に - # 適用された除外パス一覧はログにも出力し、今後 Windows lane のばらつき - # を調査するときにどのパスが対象になったかを追えるようにする。 + # 適用された除外パスは理由付きの audit table としてログと job summary に + # 出力し、どのパスをなぜ対象にしたかを追えるようにする。 - name: Exclude workspace and temp paths from Windows Defender (Windows only) if: runner.os == 'Windows' shell: pwsh run: | $candidates = @( - "${{ github.workspace }}", - $env:RUNNER_TEMP, - $env:TEMP, - $env:TMP, - [System.IO.Path]::GetTempPath(), - $env:NUGET_PACKAGES, - (Join-Path $env:USERPROFILE ".nuget\packages"), - (Join-Path $env:LOCALAPPDATA "NuGet\packages") + [pscustomobject]@{ + Path = "${{ github.workspace }}" + Reason = "Repository checkout containing build outputs and temp-heavy test fixtures." + }, + [pscustomobject]@{ + Path = $env:RUNNER_TEMP + Reason = "GitHub-hosted runner temp root used by actions and pinned TMP/TEMP." + }, + [pscustomobject]@{ + Path = $env:TEMP + Reason = "Effective TEMP path used by PowerShell and child processes." + }, + [pscustomobject]@{ + Path = $env:TMP + Reason = "Effective TMP path preferred by .NET Path.GetTempPath()." + }, + [pscustomobject]@{ + Path = [System.IO.Path]::GetTempPath() + Reason = "Runtime-observed .NET temp path, which can differ from environment variables." + }, + [pscustomobject]@{ + Path = $env:NUGET_PACKAGES + Reason = "Explicit NuGet global package cache when configured." + }, + [pscustomobject]@{ + Path = (Join-Path $env:USERPROFILE ".nuget\packages") + Reason = "Default user NuGet global package cache touched by restore/build." + }, + [pscustomobject]@{ + Path = (Join-Path $env:LOCALAPPDATA "NuGet\packages") + Reason = "Windows local NuGet package cache fallback touched by restore/build." + } ) - $paths = $candidates | - Where-Object { $_ } | - ForEach-Object { $_.TrimEnd('\','/') } | - Where-Object { $_ } | - Select-Object -Unique + $exclusions = $candidates | + Where-Object { $_.Path } | + ForEach-Object { + $path = $_.Path.TrimEnd('\','/') + if ($path) { + [pscustomobject]@{ + Path = $path + Reason = $_.Reason + } + } + } | + Group-Object -Property Path | + ForEach-Object { + [pscustomobject]@{ + Path = $_.Name + Reason = (($_.Group | ForEach-Object { $_.Reason }) | Select-Object -Unique) -join " " + } + } | + Sort-Object -Property Path + + Write-Host "Windows Defender exclusion audit:" + foreach ($entry in $exclusions) { + Write-Host (" {0} -- {1}" -f $entry.Path, $entry.Reason) + } - Write-Host "Windows Defender exclusion candidates:" - foreach ($path in $paths) { - Write-Host " $path" + if ($env:GITHUB_STEP_SUMMARY) { + "### Windows Defender exclusion audit" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + "" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + "| Path | Reason |" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + "| --- | --- |" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + foreach ($entry in $exclusions) { + $safePath = $entry.Path.Replace("|", "\|") + $safeReason = $entry.Reason.Replace("|", "\|") + ('| `{0}` | {1} |' -f $safePath, $safeReason) | + Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + } } - foreach ($path in $paths) { - Add-MpPreference -ExclusionPath $path -ErrorAction Stop + foreach ($entry in $exclusions) { + Add-MpPreference -ExclusionPath $entry.Path -ErrorAction Stop } $prefs = Get-MpPreference - foreach ($path in $paths) { - if ($prefs.ExclusionPath -notcontains $path) { - throw "Windows Defender exclusion was not applied: $path" + foreach ($entry in $exclusions) { + if ($prefs.ExclusionPath -notcontains $entry.Path) { + throw "Windows Defender exclusion was not applied: $($entry.Path)" } } @@ -148,8 +200,6 @@ jobs: ~/.nuget/packages ~\AppData\Local\NuGet\packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json', '**/*.csproj') }} - restore-keys: | - ${{ runner.os }}-nuget- # --locked-mode requires every resolved package to match the committed # packages.lock.json so an unexpected transitive bump (including silent diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 13d98d34e3..5089f88b54 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -101,9 +101,10 @@ jobs: # Get-MpPreference -notcontains check matches the stored form exactly. # Every Add-MpPreference call uses -ErrorAction Stop, and a final # Get-MpPreference verification throws if any exclusion did not register - # so the step fails loudly instead of degrading silently. The list of - # effective exclusions is also echoed to the log so future investigations - # of Windows lane variance can see exactly which paths were covered. + # so the step fails loudly instead of degrading silently. A reason-coded + # audit table of effective exclusions is emitted to both the log and job + # summary so future investigations can see exactly which paths were + # covered and why each path was required. # release workflow の Windows lane でも、テストスイートが大量に作る # 一時ファイル(temp project / SQLite DB / .cdidx / 合成ソース)を # Windows Defender が都度スキャンする影響は同じく支配的になる。 @@ -120,42 +121,93 @@ jobs: # Get-MpPreference -notcontains の照合を保存形式と完全一致させる。 # 各呼び出しを -ErrorAction Stop で明示失敗させ、最後に Get-MpPreference # で登録を検証し、silent degradation を起こさないようにする。最終的に - # 適用された除外パス一覧はログにも出力し、今後 Windows lane のばらつき - # を調査するときにどのパスが対象になったかを追えるようにする。 + # 適用された除外パスは理由付きの audit table としてログと job summary に + # 出力し、どのパスをなぜ対象にしたかを追えるようにする。 - name: Exclude workspace and temp paths from Windows Defender (Windows only) if: runner.os == 'Windows' shell: pwsh run: | $candidates = @( - "${{ github.workspace }}", - $env:RUNNER_TEMP, - $env:TEMP, - $env:TMP, - [System.IO.Path]::GetTempPath(), - $env:NUGET_PACKAGES, - (Join-Path $env:USERPROFILE ".nuget\packages"), - (Join-Path $env:LOCALAPPDATA "NuGet\packages") + [pscustomobject]@{ + Path = "${{ github.workspace }}" + Reason = "Repository checkout containing build outputs and temp-heavy test fixtures." + }, + [pscustomobject]@{ + Path = $env:RUNNER_TEMP + Reason = "GitHub-hosted runner temp root used by actions and pinned TMP/TEMP." + }, + [pscustomobject]@{ + Path = $env:TEMP + Reason = "Effective TEMP path used by PowerShell and child processes." + }, + [pscustomobject]@{ + Path = $env:TMP + Reason = "Effective TMP path preferred by .NET Path.GetTempPath()." + }, + [pscustomobject]@{ + Path = [System.IO.Path]::GetTempPath() + Reason = "Runtime-observed .NET temp path, which can differ from environment variables." + }, + [pscustomobject]@{ + Path = $env:NUGET_PACKAGES + Reason = "Explicit NuGet global package cache when configured." + }, + [pscustomobject]@{ + Path = (Join-Path $env:USERPROFILE ".nuget\packages") + Reason = "Default user NuGet global package cache touched by restore/build." + }, + [pscustomobject]@{ + Path = (Join-Path $env:LOCALAPPDATA "NuGet\packages") + Reason = "Windows local NuGet package cache fallback touched by restore/build." + } ) - $paths = $candidates | - Where-Object { $_ } | - ForEach-Object { $_.TrimEnd('\','/') } | - Where-Object { $_ } | - Select-Object -Unique + $exclusions = $candidates | + Where-Object { $_.Path } | + ForEach-Object { + $path = $_.Path.TrimEnd('\','/') + if ($path) { + [pscustomobject]@{ + Path = $path + Reason = $_.Reason + } + } + } | + Group-Object -Property Path | + ForEach-Object { + [pscustomobject]@{ + Path = $_.Name + Reason = (($_.Group | ForEach-Object { $_.Reason }) | Select-Object -Unique) -join " " + } + } | + Sort-Object -Property Path + + Write-Host "Windows Defender exclusion audit:" + foreach ($entry in $exclusions) { + Write-Host (" {0} -- {1}" -f $entry.Path, $entry.Reason) + } - Write-Host "Windows Defender exclusion candidates:" - foreach ($path in $paths) { - Write-Host " $path" + if ($env:GITHUB_STEP_SUMMARY) { + "### Windows Defender exclusion audit" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + "" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + "| Path | Reason |" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + "| --- | --- |" | Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + foreach ($entry in $exclusions) { + $safePath = $entry.Path.Replace("|", "\|") + $safeReason = $entry.Reason.Replace("|", "\|") + ('| `{0}` | {1} |' -f $safePath, $safeReason) | + Out-File -FilePath $env:GITHUB_STEP_SUMMARY -Encoding utf8 -Append + } } - foreach ($path in $paths) { - Add-MpPreference -ExclusionPath $path -ErrorAction Stop + foreach ($entry in $exclusions) { + Add-MpPreference -ExclusionPath $entry.Path -ErrorAction Stop } $prefs = Get-MpPreference - foreach ($path in $paths) { - if ($prefs.ExclusionPath -notcontains $path) { - throw "Windows Defender exclusion was not applied: $path" + foreach ($entry in $exclusions) { + if ($prefs.ExclusionPath -notcontains $entry.Path) { + throw "Windows Defender exclusion was not applied: $($entry.Path)" } } @@ -171,8 +223,6 @@ jobs: ~/.nuget/packages ~\AppData\Local\NuGet\packages key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json', '**/*.csproj') }} - restore-keys: | - ${{ runner.os }}-nuget- # --locked-mode requires every resolved package to match the committed # packages.lock.json so an unexpected transitive bump (including silent @@ -903,6 +953,8 @@ jobs: needs: create-release permissions: contents: read + id-token: write + attestations: write packages: write steps: - name: Checkout release tag @@ -953,6 +1005,8 @@ jobs: context: . platforms: linux/amd64,linux/arm64 push: true + provenance: mode=max + sbom: true tags: ${{ steps.image-tags.outputs.tags }} publish-homebrew: diff --git a/DEVELOPER_GUIDE.md b/DEVELOPER_GUIDE.md index e37d469404..0fc0f60115 100644 --- a/DEVELOPER_GUIDE.md +++ b/DEVELOPER_GUIDE.md @@ -72,6 +72,7 @@ in [DISTRIBUTION.md](DISTRIBUTION.md): | `install.sh` | Latest install, explicit-version install, `--doctor`, and local mirror self-test. | | NuGet global tool | Install/update on a clean .NET 8 tool environment. | | Release assets | Published asset exists for every advertised RID. | +| GHCR container image | Published `linux/amd64` and `linux/arm64` images run `cdidx --version`, omit runtime `git`, and expose provenance/SBOM attestations. | | Package metadata | License, repository URL, tags, and runtime prerequisites are correct. | | Documentation links | README, USER_GUIDE, and package metadata links resolve to the intended docs. | @@ -81,7 +82,7 @@ in [DISTRIBUTION.md](DISTRIBUTION.md): |---|---| | Lock-file participation | `Directory.Build.props` sets `RestorePackagesWithLockFile=true`, so every project under this solution writes a `packages.lock.json` next to its `.csproj`. The lock file pins exact resolved versions and `contentHash` for every direct **and transitive** package, including the native-bearing `SQLitePCLRaw.bundle_e_sqlite3` that ships under `Microsoft.Data.Sqlite`. This keeps builds reproducible across machines, CI lanes, and release artifacts, and turns a silent transitive bump or downgrade attack into a loud, build-breaking diff. | | Package source boundary | The repository root `nuget.config` clears machine-wide package sources, allows only `https://api.nuget.org/v3/index.json`, maps every package ID to that source, and requires signed packages. Trusted signers are limited to the NuGet.org repository-signing certificates and the author-signing certificates needed by the currently locked package graph, so restore rejects unsigned packages, packages from unconfigured feeds, and packages signed by unknown authors. When NuGet.org or an approved package author rotates a signing certificate, update `nuget.config` in the same change as the restore validation. | -| CI locked restore | CI (`.github/workflows/dotnet.yml`, `release.yml`, `codeql.yml`) restores the solution with `--locked-mode`, so any drift between the committed lock files and the resolution graph fails the build instead of slipping into artifacts. Local development restores normally; the lock file is only enforced in CI. | +| CI locked restore | CI (`.github/workflows/dotnet.yml`, `release.yml`, `codeql.yml`) restores the solution with `--locked-mode`, so any drift between the committed lock files and the resolution graph fails the build instead of slipping into artifacts. NuGet package caches in the build and release workflows restore only by the exact lockfile-derived key and do not fall back to broad OS-level cache prefixes. Local development restores normally; the lock file is only enforced in CI. | | Deterministic package metadata | The `CodeIndex` package project opts into deterministic builds and publishes repository metadata for Source Link. On GitHub Actions it also sets `ContinuousIntegrationBuild=true` and embeds untracked source inputs so PDBs and `.snupkg` artifacts can map back to the repository without local machine paths. Build metadata uses the Git commit date when available instead of the wall-clock build date so repeated builds of the same commit do not drift by timestamp. `Microsoft.SourceLink.GitHub` is a build-only dependency (`PrivateAssets=All`), not a runtime dependency. | | Vulnerability checks | The normal build/test workflow runs `dotnet list src/CodeIndex/CodeIndex.csproj package --vulnerable --include-transitive --no-restore` after locked restore and fails on any High or Critical NuGet advisory in direct or transitive runtime packages. Dependabot is configured for weekly NuGet and GitHub Actions update PRs in `.github/dependabot.yml`, so security fixes and routine dependency/action bumps are proposed before they become release surprises. | | Release publish/pack restore | The release `dotnet publish` per-RID and `dotnet pack` NuGet packaging steps intentionally do **not** set `RestoreLockedMode=true`. Those steps run runtime-specific restores that legitimately add lock entries that did not exist at solution-restore time, such as `net8.0/` runtime sections and `Microsoft.NET.ILLink.Tasks` for trimming. They still consume locked versions because `RestorePackagesWithLockFile=true` from `Directory.Build.props` forces every restore on the machine to resolve through the lock file. The supply-chain guarantee for `Microsoft.Data.Sqlite` and its `SQLitePCLRaw.*` graph is enforced by the solution-level locked restore that runs first. | @@ -2180,6 +2181,7 @@ channel をすべて確認してください。 | `install.sh` | latest install、explicit-version install、`--doctor`、local mirror self-test。 | | NuGet global tool | clean な .NET 8 tool environment での install/update。 | | release asset | advertised RID ごとに published release asset があること。 | +| GHCR container image | 公開済みの `linux/amd64` / `linux/arm64` image で `cdidx --version` が動作し、runtime `git` を含まず、provenance / SBOM attestation を公開していること。 | | package metadata | license、repository URL、tag、runtime prerequisite が正しいこと。 | | documentation link | README、USER_GUIDE、package metadata からの link が意図した docs を指すこと。 | @@ -2189,7 +2191,7 @@ channel をすべて確認してください。 |---|---| | lock ファイル参加 | `Directory.Build.props` が `RestorePackagesWithLockFile=true` を設定しているため、本 solution 配下の各 project は `.csproj` と並んで `packages.lock.json` を出力します。lock ファイルは直接依存と**推移依存**の双方について解決済み version と `contentHash` を固定し、`Microsoft.Data.Sqlite` 配下に native を含めて出荷する `SQLitePCLRaw.bundle_e_sqlite3` まで対象に含めます。これにより machine、CI lane、release artifact の再現性が保たれ、推移依存の暗黙 bump や downgrade attack が build を壊す差分として顕在化します。 | | package source 境界 | repository root の `nuget.config` は machine-wide な package source を消去し、`https://api.nuget.org/v3/index.json` だけを許可し、すべての package ID をその source に map し、署名付き package を必須にします。trusted signer は NuGet.org repository-signing certificate と、現在 lock されている package graph に必要な author-signing certificate に限定し、未署名 package、未設定 feed 由来の package、未知の author による署名 package を拒否します。NuGet.org または承認済み package author が signing certificate を rotate した場合は、restore 検証と同じ変更で `nuget.config` を更新してください。 | -| CI locked restore | CI(`.github/workflows/dotnet.yml`, `release.yml`, `codeql.yml`)は solution restore を `--locked-mode` 付きで実行し、commit 済み lock ファイルと解決結果に差分があると artifact に混入する前に build が失敗します。ローカル開発の通常 restore は従来どおりで、lock file enforcement は CI でのみ強制されます。 | +| CI locked restore | CI(`.github/workflows/dotnet.yml`, `release.yml`, `codeql.yml`)は solution restore を `--locked-mode` 付きで実行し、commit 済み lock ファイルと解決結果に差分があると artifact に混入する前に build が失敗します。build / release workflow の NuGet package cache は lockfile 由来の完全一致 key だけで復元し、OS 単位の broad cache prefix には fallback しません。ローカル開発の通常 restore は従来どおりで、lock file enforcement は CI でのみ強制されます。 | | deterministic package metadata | `CodeIndex` package project は deterministic build に opt in し、Source Link 用の repository metadata を公開します。GitHub Actions では `ContinuousIntegrationBuild=true` も設定し、untracked source input を埋め込むため、PDB と `.snupkg` artifact は local machine path なしで repository に対応付けられます。build metadata は可能な場合 wall-clock build date ではなく Git commit date を使い、同じ commit の繰り返し build が timestamp で drift しないようにします。`Microsoft.SourceLink.GitHub` は build-only dependency(`PrivateAssets=All`)であり、runtime dependency ではありません。 | | vulnerability check | 通常の build/test workflow は locked restore 後に `dotnet list src/CodeIndex/CodeIndex.csproj package --vulnerable --include-transitive --no-restore` を実行し、direct または transitive runtime package に High / Critical の NuGet advisory があると失敗します。Dependabot は `.github/dependabot.yml` で NuGet と GitHub Actions の weekly update PR を作るよう設定されているため、security fix と通常の dependency/action bump は release surprise になる前に提案されます。 | | release publish/pack restore | release の `dotnet publish`(RID ごと)と `dotnet pack`(NuGet packaging)には意図的に `RestoreLockedMode=true` を設定していません。これらは runtime-specific な restore を走らせ、solution restore 時には存在しなかった lock entry(`net8.0/` 等の runtime section や trimming 用の `Microsoft.NET.ILLink.Tasks`)を正当に追加します。それでも `Directory.Build.props` の `RestorePackagesWithLockFile=true` により、その実行 machine 上の全 restore は lock file 経由で解決されるため version は固定されたままです。`Microsoft.Data.Sqlite` および `SQLitePCLRaw.*` graph に対する supply-chain 保証は、先行する solution-level locked restore で担保されます。 | diff --git a/DISTRIBUTION.md b/DISTRIBUTION.md index d26e50239f..ecc0734717 100644 --- a/DISTRIBUTION.md +++ b/DISTRIBUTION.md @@ -9,7 +9,8 @@ This document compares supported and planned ways to install `cdidx`. | `install.sh` release assets | Linux/macOS self-contained tarballs for `linux-x64`, `linux-arm64`, and `osx-arm64` where a matching release asset exists | POSIX shell, `curl`, `tar`, and network access to the configured release host | Re-run the installer without a version for latest, or pass `vX.Y.Z` for an exact release | Supports `HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY`, `CDIDX_GITHUB_BASE_URL`, `CDIDX_GITHUB_API_BASE_URL`, and local mirror self-tests | Primary self-contained installer for terminals, CI, containers, and ARM64 Unix hosts without .NET | | Windows release ZIP assets | Windows self-contained ZIPs for `win-x64` and `win-arm64` where published | PowerShell or another ZIP extraction workflow | Download and replace with the desired release ZIP | Mirror the GitHub release ZIP and checksum assets through the same artifact controls | Supported release-asset path for Windows users who do not use NuGet | | NuGet global tool | Any platform supported by .NET 8 global tools | .NET 8 SDK for `dotnet tool install/update`; .NET 8 runtime to run the installed tool | `dotnet tool update -g cdidx` | Use standard NuGet feeds, caches, and enterprise mirrors | Portable framework-dependent tool package; not RID-specific or self-contained | -| Container or manual image build | Any base image that can run the selected install path | Either `install.sh` prerequisites or a .NET SDK for source builds | Rebuild the image with a pinned release or source revision | Mirror release assets or NuGet feeds inside the image build network | Supported as a deployment pattern, not as an official published container image | +| GHCR container image | Linux `linux/amd64` and `linux/arm64` images at `ghcr.io/widthdom/codeindex:`; stable releases also publish `latest` | Container runtime; mount the target repository at `/repo` when indexing/querying project files. The runtime image includes `ca-certificates` but not `git`; git-aware metadata is best-effort unless a derived image adds `git` | Pull a newer release tag or `latest` | Mirror the GHCR image plus its registry provenance/SBOM attestations | Official OCI image for CI and agent container use | +| Manual image build | Any base image that can run the selected install path | Either `install.sh` prerequisites or a .NET SDK for source builds | Rebuild the image with a pinned release or source revision | Mirror release assets or NuGet feeds inside the image build network | Supported as a deployment pattern for customized images | | Build from source | Windows, macOS, and Linux with a supported .NET SDK | .NET 8 SDK for production target; .NET 9 SDK if running the full test matrix | Pull source and rebuild | Works with restored package caches and internal NuGet mirrors | Contributor and advanced-user path | ## Planned or Community Channels @@ -51,6 +52,7 @@ Before publishing or updating a channel, verify: - `install.sh` can install the latest release and an explicit `vX.Y.Z` release. - `install.sh --doctor vX.Y.Z` reports the configured release and API hosts. - `dotnet tool install -g cdidx --version ` succeeds on a clean .NET 8 tool environment. +- `docker pull ghcr.io/widthdom/codeindex:` succeeds for published release images, and the registry exposes provenance/SBOM attestations. - `cdidx --version` runs from each installed channel. - `cdidx status --help` or another lightweight command runs without requiring a repository. - Package metadata preserves license, homepage, and repository links. diff --git a/Dockerfile b/Dockerfile index a1a3ae7ccb..94660048d4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ RUN case "$TARGETARCH" in \ FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine AS runtime -RUN apk add --no-cache ca-certificates git +RUN apk add --no-cache ca-certificates WORKDIR /repo COPY --from=build /out/ /usr/local/lib/cdidx/ diff --git a/changelog.d/unreleased/3495.security.md b/changelog.d/unreleased/3495.security.md new file mode 100644 index 0000000000..aafc587397 --- /dev/null +++ b/changelog.d/unreleased/3495.security.md @@ -0,0 +1,18 @@ +--- +category: security +issues: + - 3495 +affected: + - Dockerfile + - .github/workflows/release.yml + - DISTRIBUTION.md + - DEVELOPER_GUIDE.md +--- + +## English + +- **Container releases now minimize runtime git dependency and publish attestations (#3495)** — the GHCR runtime image no longer installs `git`, and release image builds now request provenance and SBOM attestations. + +## 日本語 + +- **コンテナリリースで runtime の git 依存を最小化し、attestation を公開するようにしました (#3495)** — GHCR runtime image は `git` をインストールしなくなり、release image build は provenance と SBOM の attestation を要求するようになりました。 diff --git a/changelog.d/unreleased/3496.security.md b/changelog.d/unreleased/3496.security.md new file mode 100644 index 0000000000..8a9b3fe025 --- /dev/null +++ b/changelog.d/unreleased/3496.security.md @@ -0,0 +1,17 @@ +--- +category: security +issues: + - 3496 +affected: + - .github/workflows/dotnet.yml + - .github/workflows/release.yml + - DEVELOPER_GUIDE.md +--- + +## English + +- **Release and build NuGet caches now avoid broad fallback restore keys (#3496)** — CI restores NuGet package caches only from the exact lockfile-derived key instead of falling back to an OS-wide package cache prefix. + +## 日本語 + +- **release / build の NuGet cache が broad fallback restore key を使わないようになりました (#3496)** — CI は NuGet package cache を lockfile 由来の完全一致 key からのみ復元し、OS 単位の package cache prefix へ fallback しなくなりました。 diff --git a/changelog.d/unreleased/3497.security.md b/changelog.d/unreleased/3497.security.md new file mode 100644 index 0000000000..d75e512784 --- /dev/null +++ b/changelog.d/unreleased/3497.security.md @@ -0,0 +1,16 @@ +--- +category: security +issues: + - 3497 +affected: + - .github/workflows/dotnet.yml + - .github/workflows/release.yml +--- + +## English + +- **Windows Defender CI exclusions now emit reason-coded audit records (#3497)** — Windows build and release lanes log each effective Defender exclusion path with its justification and append the same table to the job summary before applying the exclusions. + +## 日本語 + +- **Windows Defender の CI 除外が理由付き audit record を出力するようになりました (#3497)** — Windows の build / release lane は、Defender 除外を適用する前に、有効な各除外パスと理由をログと job summary に出力するようになりました。