Skip to content

test(secrets): scope-routing + roundtrip integration matrix#742

Merged
intel352 merged 1 commit into
mainfrom
test/scope-roundtrip-1779286066
May 20, 2026
Merged

test(secrets): scope-routing + roundtrip integration matrix#742
intel352 merged 1 commit into
mainfrom
test/scope-roundtrip-1779286066

Conversation

@intel352

Copy link
Copy Markdown
Contributor

Per workflow#735 SPEC T20. Httptest stub captures PUT paths + decrypts payloads end-to-end across repo/env/org × visibility levels. 6 subtests.

Per workflow#735 SPEC T20.

secrets/github_scope_integration_test.go (235 LoC, 6 subtests +
2 root tests):

- roundtripStub: httptest.Server that records every request +
  decrypts every PUT body using a stub key pair generated per-
  test. Mirrors the encryptSecret blake2b-nonce sealed-box
  convention exactly.

- TestScope_Integration_Matrix exercises every scope path:
    repo:        /repos/acme/repo/actions/secrets/REPO_SECRET
    env:         /repos/acme/repo/environments/staging/secrets/ENV_SECRET
    org-all:     /orgs/acme/actions/secrets/ORG_SECRET           + visibility=all
    org-private: /orgs/acme/actions/secrets/PRIVATE_SECRET       + visibility=private
    org-selected:/orgs/acme/actions/secrets/SELECTED_SECRET      + visibility=selected
  Each subtest asserts:
    1. PUT path matches the scope's URL prefix.
    2. Encrypted body decrypts back to the original plaintext.
    3. visibility field is present on org PUTs + absent on repo/env.

- TestScope_Integration_SelectedRepoIDsPropagate verifies that
  the selected_repository_ids array is serialised correctly
  into the org PUT payload when visibility=selected.

Closes the end-to-end test gap for the scoped-secret-set feature.
All existing wfctl + secrets tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 20, 2026 14:11
@intel352 intel352 merged commit a4936c4 into main May 20, 2026
@intel352 intel352 deleted the test/scope-roundtrip-1779286066 branch May 20, 2026 14:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an end-to-end integration test matrix for the GitHub Actions secrets provider, validating scope-based URL routing (repo/env/org) and verifying encrypted payloads can be decrypted back to the original plaintext (roundtrip) via an httptest stub.

Changes:

  • Introduces a roundtripStub httptest server that serves /public-key, records PUTs, and decrypts encrypted_value for assertions.
  • Adds a scope/visibility matrix test covering repo, environment, and org secrets (including org visibility modes).
  • Adds a focused test ensuring selected_repository_ids serializes correctly for org visibility selected.

Comment on lines +3 to +18
import (
"context"
"encoding/base64"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"sync"
"testing"

"crypto/rand"

"golang.org/x/crypto/blake2b"
"golang.org/x/crypto/nacl/box"
)
Comment on lines +21 to +22
// every request + decrypts every PUT body using a deterministic key
// pair (generated per-test). Used by the T20 integration matrix.
Comment on lines +82 to +110
// decrypt inverts encryptSecret. The wire shape is:
//
// eph_pub_key (32 bytes) || box.Seal(plaintext, nonce, recipient, eph_priv)
//
// where nonce = blake2b-192(eph_pub || recipient_pub) per libsodium
// sealed-box.
func (s *roundtripStub) decrypt(encB64 string) (string, bool) {
cipher, err := base64.StdEncoding.DecodeString(encB64)
if err != nil || len(cipher) < 32 {
return "", false
}
var ephPub [32]byte
copy(ephPub[:], cipher[:32])

h, err := blake2b.New(24, nil)
if err != nil {
return "", false
}
h.Write(ephPub[:])
h.Write(s.pubKey[:])
var nonce [24]byte
copy(nonce[:], h.Sum(nil))

plain, ok := box.Open(nil, cipher[32:], &nonce, &ephPub, &s.privKey)
if !ok {
return "", false
}
return string(plain), true
}
Comment on lines +127 to +134
cases := []struct {
name string
buildProv func(t *testing.T, base string) *GitHubSecretsProvider
secret string
value string
wantPath string
extraPayload map[string]any
}{
@github-actions

Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:276: parsing iteration count: invalid syntax
baseline-bench.txt:316615: parsing iteration count: invalid syntax
baseline-bench.txt:611054: parsing iteration count: invalid syntax
baseline-bench.txt:912294: parsing iteration count: invalid syntax
baseline-bench.txt:1226494: parsing iteration count: invalid syntax
baseline-bench.txt:1505060: parsing iteration count: invalid syntax
benchmark-results.txt:276: parsing iteration count: invalid syntax
benchmark-results.txt:354982: parsing iteration count: invalid syntax
benchmark-results.txt:680729: parsing iteration count: invalid syntax
benchmark-results.txt:973215: parsing iteration count: invalid syntax
benchmark-results.txt:1264369: parsing iteration count: invalid syntax
benchmark-results.txt:1587881: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4               9.253m ± 66%
ComponentLoad-4                     3.600m ±  2%
ComponentExecute-4                  1.964µ ±  1%
PoolContention/workers-1-4          1.109µ ±  1%
PoolContention/workers-2-4          1.081µ ±  1%
PoolContention/workers-4-4          1.081µ ±  3%
PoolContention/workers-8-4          1.087µ ±  3%
PoolContention/workers-16-4         1.088µ ±  0%
ComponentLifecycle-4                3.623m ±  1%
SourceValidation-4                  2.309µ ±  1%
RegistryConcurrent-4                782.8n ±  4%
LoaderLoadFromString-4              3.641m ±  0%
geomean                             19.12µ

                            │ baseline-bench.txt │
                            │        B/op        │
InterpreterCreation-4               2.027Mi ± 0%
ComponentLoad-4                     2.180Mi ± 0%
ComponentExecute-4                  1.203Ki ± 0%
PoolContention/workers-1-4          1.203Ki ± 0%
PoolContention/workers-2-4          1.203Ki ± 0%
PoolContention/workers-4-4          1.203Ki ± 0%
PoolContention/workers-8-4          1.203Ki ± 0%
PoolContention/workers-16-4         1.203Ki ± 0%
ComponentLifecycle-4                2.183Mi ± 0%
SourceValidation-4                  1.984Ki ± 0%
RegistryConcurrent-4                1.133Ki ± 0%
LoaderLoadFromString-4              2.182Mi ± 0%
geomean                             15.25Ki

                            │ baseline-bench.txt │
                            │     allocs/op      │
InterpreterCreation-4                15.68k ± 0%
ComponentLoad-4                      18.02k ± 0%
ComponentExecute-4                    25.00 ± 0%
PoolContention/workers-1-4            25.00 ± 0%
PoolContention/workers-2-4            25.00 ± 0%
PoolContention/workers-4-4            25.00 ± 0%
PoolContention/workers-8-4            25.00 ± 0%
PoolContention/workers-16-4           25.00 ± 0%
ComponentLifecycle-4                 18.07k ± 0%
SourceValidation-4                    32.00 ± 0%
RegistryConcurrent-4                  2.000 ± 0%
LoaderLoadFromString-4               18.06k ± 0%
geomean                               183.3

cpu: AMD EPYC 9V74 80-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  7.652m ± 61%
ComponentLoad-4                        3.517m ±  2%
ComponentExecute-4                     1.822µ ±  1%
PoolContention/workers-1-4             1.028µ ±  1%
PoolContention/workers-2-4             1.031µ ±  1%
PoolContention/workers-4-4             1.019µ ±  3%
PoolContention/workers-8-4             1.012µ ±  0%
PoolContention/workers-16-4            1.023µ ±  2%
ComponentLifecycle-4                   3.551m ±  1%
SourceValidation-4                     2.093µ ±  3%
RegistryConcurrent-4                   746.6n ±  5%
LoaderLoadFromString-4                 3.602m ±  1%
geomean                                17.92µ

                            │ benchmark-results.txt │
                            │         B/op          │
InterpreterCreation-4                  2.027Mi ± 0%
ComponentLoad-4                        2.180Mi ± 0%
ComponentExecute-4                     1.203Ki ± 0%
PoolContention/workers-1-4             1.203Ki ± 0%
PoolContention/workers-2-4             1.203Ki ± 0%
PoolContention/workers-4-4             1.203Ki ± 0%
PoolContention/workers-8-4             1.203Ki ± 0%
PoolContention/workers-16-4            1.203Ki ± 0%
ComponentLifecycle-4                   2.183Mi ± 0%
SourceValidation-4                     1.984Ki ± 0%
RegistryConcurrent-4                   1.133Ki ± 0%
LoaderLoadFromString-4                 2.182Mi ± 0%
geomean                                15.25Ki

                            │ benchmark-results.txt │
                            │       allocs/op       │
InterpreterCreation-4                   15.68k ± 0%
ComponentLoad-4                         18.02k ± 0%
ComponentExecute-4                       25.00 ± 0%
PoolContention/workers-1-4               25.00 ± 0%
PoolContention/workers-2-4               25.00 ± 0%
PoolContention/workers-4-4               25.00 ± 0%
PoolContention/workers-8-4               25.00 ± 0%
PoolContention/workers-16-4              25.00 ± 0%
ComponentLifecycle-4                    18.07k ± 0%
SourceValidation-4                       32.00 ± 0%
RegistryConcurrent-4                     2.000 ± 0%
LoaderLoadFromString-4                  18.06k ± 0%
geomean                                  183.3

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  289.1n ± 5%
CircuitBreakerExecution_Success-4          21.52n ± 0%
CircuitBreakerExecution_Failure-4          66.77n ± 0%
geomean                                    74.62n

                                  │ baseline-bench.txt │
                                  │        B/op        │
CircuitBreakerDetection-4                 144.0 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │
                                  │     allocs/op      │
CircuitBreakerDetection-4                 1.000 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                    297.1n ± 14%
CircuitBreakerExecution_Success-4            22.68n ±  0%
CircuitBreakerExecution_Failure-4            70.97n ±  0%
geomean                                      78.21n

                                  │ benchmark-results.txt │
                                  │         B/op          │
CircuitBreakerDetection-4                    144.0 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

                                  │ benchmark-results.txt │
                                  │       allocs/op       │
CircuitBreakerDetection-4                    1.000 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
IaCStateBackend_InProcess-4              307.7n ± 23%
IaCStateBackend_GRPC-4                   9.463m ±  2%
JQTransform_Simple-4                     661.3n ± 49%
JQTransform_ObjectConstruction-4         1.599µ ±  1%
JQTransform_ArraySelect-4                3.575µ ±  0%
JQTransform_Complex-4                    39.74µ ±  1%
JQTransform_Throughput-4                 1.961µ ±  0%
SSEPublishDelivery-4                     72.03n ±  1%
geomean                                  3.971µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4              416.0 ± 0%
IaCStateBackend_GRPC-4                 5.954Mi ± 4%
JQTransform_Simple-4                   1.273Ki ± 0%
JQTransform_ObjectConstruction-4       1.773Ki ± 0%
JQTransform_ArraySelect-4              2.625Ki ± 0%
JQTransform_Complex-4                  16.22Ki ± 0%
JQTransform_Throughput-4               1.984Ki ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │
                                 │     allocs/op      │
IaCStateBackend_InProcess-4              2.000 ± 0%
IaCStateBackend_GRPC-4                  6.835k ± 0%
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    324.0 ± 0%
JQTransform_Throughput-4                 17.00 ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
IaCStateBackend_InProcess-4                 298.7n ± 25%
IaCStateBackend_GRPC-4                      10.33m ±  2%
JQTransform_Simple-4                        642.6n ± 32%
JQTransform_ObjectConstruction-4            1.436µ ±  2%
JQTransform_ArraySelect-4                   3.465µ ±  1%
JQTransform_Complex-4                       42.16µ ±  1%
JQTransform_Throughput-4                    1.772µ ±  1%
SSEPublishDelivery-4                        64.54n ±  1%
geomean                                     3.843µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                 416.0 ± 0%
IaCStateBackend_GRPC-4                    5.821Mi ± 7%
JQTransform_Simple-4                      1.273Ki ± 0%
JQTransform_ObjectConstruction-4          1.773Ki ± 0%
JQTransform_ArraySelect-4                 2.625Ki ± 0%
JQTransform_Complex-4                     16.22Ki ± 0%
JQTransform_Throughput-4                  1.984Ki ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                 │ benchmark-results.txt │
                                 │       allocs/op       │
IaCStateBackend_InProcess-4                 2.000 ± 0%
IaCStateBackend_GRPC-4                     6.866k ± 0%
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       324.0 ± 0%
JQTransform_Throughput-4                    17.00 ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 7763 64-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                    1.106µ ± 6%
SchemaValidation_AllFields-4                 1.649µ ± 2%
SchemaValidation_FormatValidation-4          1.593µ ± 2%
SchemaValidation_ManySchemas-4               1.840µ ± 3%
geomean                                      1.520µ

                                    │ baseline-bench.txt │
                                    │        B/op        │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │
                                    │     allocs/op      │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                      1.091µ ± 16%
SchemaValidation_AllFields-4                   1.635µ ±  5%
SchemaValidation_FormatValidation-4            1.565µ ±  4%
SchemaValidation_ManySchemas-4                 1.600µ ±  1%
geomean                                        1.453µ

                                    │ benchmark-results.txt │
                                    │         B/op          │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

                                    │ benchmark-results.txt │
                                    │       allocs/op       │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.167µ ± 39%
EventStoreAppend_SQLite-4                  1.256m ±  4%
GetTimeline_InMemory/events-10-4           13.92µ ±  3%
GetTimeline_InMemory/events-50-4           77.86µ ± 18%
GetTimeline_InMemory/events-100-4          125.8µ ±  1%
GetTimeline_InMemory/events-500-4          652.8µ ±  1%
GetTimeline_InMemory/events-1000-4         1.360m ±  1%
GetTimeline_SQLite/events-10-4             110.0µ ±  1%
GetTimeline_SQLite/events-50-4             258.4µ ±  1%
GetTimeline_SQLite/events-100-4            438.3µ ±  1%
GetTimeline_SQLite/events-500-4            1.891m ±  1%
GetTimeline_SQLite/events-1000-4           3.659m ±  1%
geomean                                    223.2µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  798.5 ± 7%
EventStoreAppend_SQLite-4                  1.985Ki ± 1%
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%
geomean                                    67.41Ki

                                   │ baseline-bench.txt │
                                   │     allocs/op      │
EventStoreAppend_InMemory-4                  7.000 ± 0%
EventStoreAppend_SQLite-4                    53.00 ± 0%
GetTimeline_InMemory/events-10-4             125.0 ± 0%
GetTimeline_InMemory/events-50-4             653.0 ± 0%
GetTimeline_InMemory/events-100-4           1.306k ± 0%
GetTimeline_InMemory/events-500-4           6.514k ± 0%
GetTimeline_InMemory/events-1000-4          13.02k ± 0%
GetTimeline_SQLite/events-10-4               382.0 ± 0%
GetTimeline_SQLite/events-50-4              1.852k ± 0%
GetTimeline_SQLite/events-100-4             3.681k ± 0%
GetTimeline_SQLite/events-500-4             18.54k ± 0%
GetTimeline_SQLite/events-1000-4            37.29k ± 0%
geomean                                     1.162k

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.067µ ± 13%
EventStoreAppend_SQLite-4                     1.056m ±  2%
GetTimeline_InMemory/events-10-4              12.49µ ±  2%
GetTimeline_InMemory/events-50-4              68.82µ ± 20%
GetTimeline_InMemory/events-100-4             109.8µ ±  1%
GetTimeline_InMemory/events-500-4             562.1µ ±  1%
GetTimeline_InMemory/events-1000-4            1.140m ±  0%
GetTimeline_SQLite/events-10-4                86.43µ ±  1%
GetTimeline_SQLite/events-50-4                222.6µ ±  1%
GetTimeline_SQLite/events-100-4               389.2µ ±  1%
GetTimeline_SQLite/events-500-4               1.672m ±  1%
GetTimeline_SQLite/events-1000-4              3.262m ±  1%
geomean                                       193.7µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                    763.5 ± 12%
EventStoreAppend_SQLite-4                    1.983Ki ±  1%
GetTimeline_InMemory/events-10-4             7.953Ki ±  0%
GetTimeline_InMemory/events-50-4             46.62Ki ±  0%
GetTimeline_InMemory/events-100-4            94.48Ki ±  0%
GetTimeline_InMemory/events-500-4            472.8Ki ±  0%
GetTimeline_InMemory/events-1000-4           944.3Ki ±  0%
GetTimeline_SQLite/events-10-4               16.74Ki ±  0%
GetTimeline_SQLite/events-50-4               87.14Ki ±  0%
GetTimeline_SQLite/events-100-4              175.4Ki ±  0%
GetTimeline_SQLite/events-500-4              846.1Ki ±  0%
GetTimeline_SQLite/events-1000-4             1.639Mi ±  0%
geomean                                      67.15Ki

                                   │ benchmark-results.txt │
                                   │       allocs/op       │
EventStoreAppend_InMemory-4                     7.000 ± 0%
EventStoreAppend_SQLite-4                       53.00 ± 0%
GetTimeline_InMemory/events-10-4                125.0 ± 0%
GetTimeline_InMemory/events-50-4                653.0 ± 0%
GetTimeline_InMemory/events-100-4              1.306k ± 0%
GetTimeline_InMemory/events-500-4              6.514k ± 0%
GetTimeline_InMemory/events-1000-4             13.02k ± 0%
GetTimeline_SQLite/events-10-4                  382.0 ± 0%
GetTimeline_SQLite/events-50-4                 1.852k ± 0%
GetTimeline_SQLite/events-100-4                3.681k ± 0%
GetTimeline_SQLite/events-500-4                18.54k ± 0%
GetTimeline_SQLite/events-1000-4               37.29k ± 0%
geomean                                        1.162k

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants