| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "fmt" |
| 5 | "reflect" |
| 6 | "testing" |
| 7 | ) |
| 8 | |
| 9 | func TestRepositoryReleaseSigningContract(t *testing.T) { |
| 10 | root := "../.." |
| 11 | contract, err := loadAndValidate(root) |
| 12 | if err != nil { |
| 13 | t.Fatal(err) |
| 14 | } |
| 15 | fingerprint, err := contractFingerprint(root, contract) |
| 16 | if err != nil { |
| 17 | t.Fatal(err) |
| 18 | } |
| 19 | if got := fmt.Sprintf("%x", fingerprint); len(got) != 64 { |
| 20 | t.Fatalf("fingerprint length = %d, want 64", len(got)) |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | func TestTopLevelSignPathWorkflowCallGraph(t *testing.T) { |
| 25 | got, err := discoverTopLevelSigningWorkflows("../..") |
| 26 | if err != nil { |
| 27 | t.Fatal(err) |
| 28 | } |
| 29 | want := []string{ |
| 30 | ".github/workflows/certum-signing-smoke.yml", |
| 31 | ".github/workflows/release-candidate.yml", |
| 32 | ".github/workflows/release-desktop.yml", |
| 33 | ".github/workflows/release-promote.yml", |
| 34 | ".github/workflows/release-stable.yml", |
| 35 | } |
| 36 | if !reflect.DeepEqual(got, want) { |
| 37 | t.Fatalf("top-level workflows that reach SignPath = %v, want %v", got, want) |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | func TestReleaseSigningContractRejectsWildcards(t *testing.T) { |
| 42 | contract, err := loadAndValidate("../..") |
| 43 | if err != nil { |
| 44 | t.Fatal(err) |
| 45 | } |
| 46 | contract.AllowedBuildDefinitions = []string{".github/workflows/release-*.yml"} |
| 47 | if err := validateContract("../..", contract); err == nil { |
| 48 | t.Fatal("wildcard build definition unexpectedly passed validation") |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | func TestWorkflowUsingSignPathTokenIsSigningEntryPoint(t *testing.T) { |
| 53 | workflow := []byte(` |
| 54 | on: workflow_dispatch |
| 55 | jobs: |
| 56 | sign: |
| 57 | runs-on: windows-latest |
| 58 | steps: |
| 59 | - shell: pwsh |
| 60 | env: |
| 61 | SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }} |
| 62 | run: ./submit-signing-request.ps1 |
| 63 | `) |
| 64 | info, err := parseWorkflow(workflow) |
| 65 | if err != nil { |
| 66 | t.Fatal(err) |
| 67 | } |
| 68 | if !info.externallyTriggered || !info.directSigning { |
| 69 | t.Fatalf("token-backed workflow was not classified as a signing entry point: %+v", info) |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | func TestWorkflowUsingCertumTokenIsSigningEntryPoint(t *testing.T) { |
| 74 | info, err := parseWorkflow([]byte(` |
| 75 | on: workflow_dispatch |
| 76 | jobs: |
| 77 | sign: |
| 78 | runs-on: windows-2022 |
| 79 | steps: |
| 80 | - uses: ./.github/actions/setup-certum |
| 81 | with: |
| 82 | otp-uri: ${{ secrets.CERTUM_OTP_URI }} |
| 83 | `)) |
| 84 | if err != nil { |
| 85 | t.Fatal(err) |
| 86 | } |
| 87 | if !info.externallyTriggered || !info.directSigning { |
| 88 | t.Fatalf("Certum signing entry point not detected: %+v", info) |
| 89 | } |
| 90 | } |
| 91 |