Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 3 additions & 20 deletions .github/workflows/native-abi.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: AGPL-3.0-only
name: Native ABI
name: Native build
on:
workflow_call:
outputs:
Expand Down Expand Up @@ -133,7 +133,7 @@ jobs:
restore-keys: |
sccache-${{ runner.os }}-${{ runner.arch }}-${{ env.SCCACHE_VERSION }}-${{ steps.vcpkg-toolchain.outputs.fingerprint }}-
- run: dotnet restore DesktopPlatform.slnx --locked-mode
- name: Build, test, and stage both CMake profiles
- name: Build and stage both CMake profiles
shell: cmd
run: |
@echo on
Expand All @@ -155,7 +155,6 @@ jobs:
for %%p in (runtime-shared shim-static) do (
cmake --preset win-x64-%%p || exit /b 1
cmake --build --preset win-x64-%%p || exit /b 1
ctest --preset win-x64-%%p || exit /b 1
cmake --install artifacts/cmake/win-x64/%%p || exit /b 1
)

Expand All @@ -173,23 +172,7 @@ jobs:
if ($nonCacheable -gt 0) {
throw "sccache reported $nonCacheable non-cacheable compilations; debug information must stay Embedded."
}
- name: Run managed P/Invoke over app-local CMake artifacts
shell: pwsh
run: |
dotnet build tests/NativeAbiTests/ArcForges.Tests.NativeAbiTests.csproj -c Release --no-restore
if ($LASTEXITCODE) { throw 'Managed native ABI test build failed.' }
$runtime = Join-Path '${{ github.workspace }}' 'artifacts/stage/native/win-x64/native'
$testOutput = Join-Path '${{ github.workspace }}' 'artifacts/bin/dotnet/windows/ArcForges.Tests.NativeAbiTests/Release/net10.0'
$nativeDlls = @(Get-ChildItem -LiteralPath $runtime -File -Filter '*.dll')
if (-not $nativeDlls.Count) { throw 'CMake staged no native runtime DLLs.' }
try {
Copy-Item -LiteralPath $nativeDlls.FullName -Destination $testOutput
& (Join-Path $testOutput 'ArcForges.Tests.NativeAbiTests.exe')
if ($LASTEXITCODE) { throw 'Managed P/Invoke over CMake artifacts failed.' }
} finally {
$nativeDlls | ForEach-Object { Remove-Item -LiteralPath (Join-Path $testOutput $_.Name) -Force -ErrorAction SilentlyContinue }
}
- name: Stage audited native runtime packages from the tested CMake outputs
- name: Stage audited native runtime packages from the compiled CMake outputs
id: native-artifact
shell: pwsh
run: |
Expand Down
43 changes: 0 additions & 43 deletions .github/workflows/package-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ jobs:
with:
name: ${{ inputs.native_artifact_name }}
path: artifacts/native-packages
- name: Verify the native artifact belongs to this source commit
run: python eng/packaging/native.py verify --commit "$GITHUB_SHA"
- run: dotnet restore DesktopPlatform.slnx --locked-mode
- run: dotnet format DesktopPlatform.slnx --verify-no-changes --no-restore
- name: Build and test platform ownership
Expand All @@ -78,44 +76,3 @@ jobs:
path: artifacts/packages/
if-no-files-found: error
retention-days: 30
consumer:
needs: pack
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version-file: .python-version
- uses: actions/setup-dotnet@a98b56852c35b8e3190ac28c8c2271da59106c68 # v6
with:
global-json-file: global.json
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: ${{ needs.pack.outputs.artifact_name }}
path: artifacts/packages
- name: Consume exact candidate outside the repository with an empty cache
env:
PACKAGE_VERSION: ${{ needs.pack.outputs.version }}
shell: pwsh
run: |
python eng/packaging/packages.py smoke --version $env:PACKAGE_VERSION --commit $env:GITHUB_SHA
if ($LASTEXITCODE) { throw 'Independent NuGet consumer verification failed.' }
- name: Publish and run Native AOT consumers of every actual Windows runtime package
if: runner.os == 'Windows'
env:
PACKAGE_VERSION: ${{ needs.pack.outputs.version }}
shell: pwsh
run: |
python eng/packaging/native_consumer.py --version $env:PACKAGE_VERSION --commit $env:GITHUB_SHA
if ($LASTEXITCODE) { throw 'Packaged native C ABI / Native AOT consumer verification failed.' }
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
if: always() && runner.os == 'Windows'
with:
name: native-consumer-evidence-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/native-consumer-evidence/
if-no-files-found: ignore
retention-days: 30
48 changes: 12 additions & 36 deletions .github/workflows/pr-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,7 @@ jobs:
run: pre-commit run --all-files --show-diff-on-failure --color=always

design-policy:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
Expand All @@ -100,17 +96,13 @@ jobs:
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
if: always()
with:
name: design-policy-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
name: design-policy-ubuntu-latest-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/evidence/design-policy.json
if-no-files-found: error
retention-days: 30

licence-policy:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
Expand All @@ -131,17 +123,13 @@ jobs:
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
if: always()
with:
name: licence-policy-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
name: licence-policy-ubuntu-latest-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/evidence/licence-*.json
if-no-files-found: error
retention-days: 30

reference-policy:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
Expand All @@ -157,17 +145,13 @@ jobs:
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
if: always()
with:
name: reference-policy-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
name: reference-policy-ubuntu-latest-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/evidence/reference-baselines.json
if-no-files-found: error
retention-days: 30

runtime-policy:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
Expand All @@ -187,17 +171,13 @@ jobs:
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
if: always()
with:
name: runtime-policy-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
name: runtime-policy-ubuntu-latest-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/evidence/runtime-ownership.json
if-no-files-found: error
retention-days: 30

reconciliation-policy:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
Expand All @@ -214,17 +194,13 @@ jobs:
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
if: always()
with:
name: reconciliation-policy-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
name: reconciliation-policy-ubuntu-latest-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/evidence/reconciliation.json
if-no-files-found: error
retention-days: 30

provenance-policy:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
Expand All @@ -246,7 +222,7 @@ jobs:
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
if: always()
with:
name: provenance-policy-${{ matrix.os }}-${{ github.run_id }}-${{ github.run_attempt }}
name: provenance-policy-ubuntu-latest-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/evidence/provenance.json
if-no-files-found: error
retention-days: 30
Expand Down
30 changes: 0 additions & 30 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,3 @@ repos:
- id: clang-format
files: ^native/.*\.(c|h|cpp|hpp|cc|hh|cxx|hxx|ipp|tpp|inc|m|mm)$
types_or: [c++, c, objective-c]

- repo: local
hooks:
# win.slnx is maintained independently of CMake and is deliberately not built by CI: the hosted
# Windows job builds the CMake presets only. Without a local gate the two Windows entry points would
# drift silently, so this runs on push, on Windows, where MSBuild and the user-wide vcpkg integration
# actually exist.
#
# It is a pre-push hook rather than pre-commit because a full native link is far too slow to sit in
# front of every commit. The Ubuntu repository-hooks job runs the default (pre-commit) stage and so
# never reaches this hook; the os.name guard makes the skip explicit rather than incidental, so the
# hook is also harmless if someone runs every stage on Linux.
#
# The body is an inline command by design: repository policy forbids tracked .ps1/.sh helpers, and
# RepositoryPolicyTests enforces that.
- id: win-slnx-release-x64
name: win.slnx Release|x64 (Windows only)
language: system
stages: [pre-push]
pass_filenames: false
always_run: true
entry: >-
python -c 'import os,subprocess,sys;
(sys.exit(0) if os.name != "nt" else None);
vswhere = os.path.expandvars(r"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe");
found = subprocess.run([vswhere, "-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild",
"-find", r"MSBuild\**\Bin\MSBuild.exe"], capture_output=True, text=True).stdout.splitlines();
(sys.exit("MSBuild was not found; install the Visual Studio C++ workload.") if not found else None);
sys.exit(subprocess.run([found[0].strip(), "win.slnx", "-m", "-restore:false",
"-p:Configuration=Release", "-p:Platform=x64", "-v:minimal", "-clp:Summary"]).returncode)'
9 changes: 9 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,12 @@ The accepted architecture lives in [ArcForges-Design](https://github.com/ArcForg
Do not add tracked PowerShell or shell helper scripts.
- Record what actually ran. A successful package-policy smoke does not prove native capability AOT,
product behavior, release signing or NuGet publication. Run the checks documented in the README.

## Validation policy (P2-017)

Follow the [current CI/local authority](https://github.com/ArcForges/ArcForges-Design/blob/47db6670a727317939b91245e8c0b288834acf99/docs/assurance/ci-and-local-validation-policy.md).
- Never add or execute macOS CI, native/runtime/package-consumer execution, GUI, browser, device, live-service or published-package installation tests in any CI trigger or nested build script.
- Keep necessary Windows/Linux compilation, packaging, targeted offline unit/static checks and non-duplicated security checks. Runtime diagnostics are explicit local opt-in only for affected behavior using existing tools. Do not silently build/test from commit or push hooks.
- Preserve locks, required signatures, licence/provenance and one identity/integrity check at each real trust handoff. Do not routinely download public artifacts or repeat archive/hash/consumer verification after publication. Narrow FFmpeg licence/configuration and Windows signature inspection remain legal admission checks.
- Do not reinstall vcpkg, SDKs or toolchains to expand validation. Do not create tags or republish solely for verification. Stop on a network failure and report the exact operation; no proxy configuration, port 7890, wsl.exe or WSL wrappers.
- Record removed coverage honestly. Review the complete latest PR and merge only after applicable checks succeed. Post-merge work stops after commit/job/publication status and a clean primary fast-forward; retain branches/worktrees.
16 changes: 9 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ Use an isolated `.worktree/` branch and the [README verification commands](READM
Shared mechanism changes belong here; product rules and business RPC schemas belong to their owners.
Keep C# 14, C++20, explicit source provenance, committed dependency locks and warnings-as-errors.

PR CI validates the managed solution, package metadata and a clean package consumer on Windows and Linux,
Windows native CMake/ABI probes, formatting, dependency review and secret scanning. Weekly/manual deep
checks retain C# CodeQL and Linux native clang-tidy, sanitizers and fuzzers. Native publication is a later
capability admission with per-RID AOT, licence and dependency evidence, not a consequence of passing probes.
PR CI compiles/stages Windows native outputs, builds/packages the managed solution on Linux,
and runs targeted offline architecture/policy tests, formatting, dependency review and secret scanning.
Weekly/manual Deep check retains C# CodeQL only. No macOS, native runtime, installed-consumer,
GUI/device/browser or live-service CI is permitted under [AGENTS.md](AGENTS.md).

Run `pre-commit run --all-files`; the Windows `win-slnx-release-x64` pre-push hook checks the independent
IDE build. Include the actual commands/results and any unverified boundary in the PR description.
The [packaging guide](eng/packaging/README.md) explains candidate and release flows.
Run relevant format/static checks once. The independent IDE build and runtime diagnostics are explicit
local opt-in when affected, never automatic pre-push work. Reuse installed tools and dependencies.
Include actual results and untested coverage in the PR description. Publication completion uses
provider status, without public package re-downloads or repeated hash/consumer checks.
The [packaging guide](eng/packaging/README.md) explains the reduced candidate and release flows.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ maintained in [ArcForges-Design](https://github.com/ArcForges/ArcForges-Design).
`eng/policy` contains generated glossary and invariant data from the exact Design
commit in `design-source.json`. The portable checker compares fresh exports and
validates document links, scoped citations, occurrence classifications and the
work-package graph. CI requires these checks on Windows and Linux before packaging.
work-package graph. CI requires these platform-independent checks once on Linux before packaging.

```text
python -m unittest discover -s eng -p test_design_policy.py -v
Expand Down Expand Up @@ -55,8 +55,8 @@ python eng/licence_boundary.py --evaluate-managed
## Build and verify

Source reuse and the existing native artifact closure are enforced by the
[provenance records and review process](docs/provenance.md). Windows and Linux CI
check the real inventory, immutable history and failure tests before packaging.
[provenance records and review process](docs/provenance.md). Linux policy CI
checks the real inventory, immutable history and failure tests before packaging.

Install the .NET SDK selected by `global.json` and Python 3.11 or newer. No Mobile/Web workloads are needed.

Expand All @@ -69,12 +69,12 @@ dotnet test --project tests/ArchitectureTests/ArcForges.Tests.ArchitectureTests.
CMake 4.3.3, Ninja 1.13.1, sccache and a C++20 compiler are needed only for native producer builds.
Follow [native prerequisites and commands](deploy/README.md). `win.slnx` additionally builds the native
Windows projects and stages their DLLs for `NativeAbiTests`; CI uses the independent CMake path.
After native staging, follow the [complete package verification](eng/packaging/README.md) to pack and
run independent C#, Native AOT and C17 consumers. See [native package scope and evidence](docs/native-package-release.md).
After native staging, follow [package production](eng/packaging/README.md). C#, Native AOT and C17
consumer diagnostics are explicit local opt-in only when an affected behavior needs them. See [native package scope and evidence](docs/native-package-release.md).

The scheduled/manual [Deep check](.github/workflows/deep-check.yml) runs C# CodeQL only.
C++ verification uses the PR/release native compilation, CMake/CTest, managed ABI tests and isolated
package consumers; Deep check no longer runs native clang-tidy, sanitizers or fuzzers. To validate the
C++ CI compiles and stages the Windows native libraries. CTest, managed ABI execution and isolated
package consumers are local opt-in only; no macOS or hosted runtime testing is permitted. To validate the
current configuration, use Actions → Deep check → Run workflow and select the desired branch.
Re-running a historical workflow uses its original commit and can still execute the removed jobs.

Expand All @@ -84,7 +84,7 @@ Re-running a historical workflow uses its original commit and can still execute
NuGet trusted-publisher setup and consumer examples. Only admitted packages are published; shared
placeholders remain excluded. These runtime packages expose the existing ABI, not future product APIs.
Every push to `main`, including a merged PR, automatically allocates a prerelease version. Native
compilation/tests and source checks must finish before packing; isolated package consumers and the
compilation and source checks must finish before packing; targeted offline checks and the
aggregate gate must pass before the same package bytes are published to nuget.org through OIDC.
No manual workflow run, version entry or publish checkbox is required.

Expand Down
Loading
Loading