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
50 changes: 42 additions & 8 deletions .github/workflows/core-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@ name: Core integration
on:
workflow_call:
inputs:
stack_sha:
description: Full NeKiro Stack commit SHA that owns this workflow
required: true
type: string
core_sha:
description: Full NeKiro Core commit SHA to assemble
required: true
type: string
workflow_dispatch:
inputs:
stack_sha:
description: Full NeKiro Stack commit SHA to assemble
required: true
type: string
core_sha:
description: Full NeKiro Core commit SHA to assemble
required: true
Expand All @@ -18,7 +26,7 @@ permissions:
contents: read

concurrency:
group: core-stack-${{ inputs.core_sha }}
group: core-stack-${{ inputs.stack_sha }}-${{ inputs.core_sha }}
cancel-in-progress: true

jobs:
Expand All @@ -30,7 +38,18 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: NeKiro-project/NeKiro-Stack
ref: main
ref: ${{ inputs.stack_sha }}

- name: Validate exact Stack revision
shell: bash
env:
STACK_SHA: ${{ inputs.stack_sha }}
run: |
if [[ ! "$STACK_SHA" =~ ^[0-9a-f]{40}$ ]]; then
echo 'stack_sha must be one full lowercase commit SHA.' >&2
exit 1
fi
test "$(git rev-parse HEAD)" = "$STACK_SHA"

- name: Set up Go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00
Expand Down Expand Up @@ -65,12 +84,16 @@ jobs:
run: |
./scripts/prepare.sh "$NEKIRO_STACK_MANIFEST" "$WORK_ROOT" "$PREPARED_ENV"
source "$PREPARED_ENV"
for name in NEKIRO_CONTROL_PLANE_IMAGE NEKIRO_A2A_ROUTER_IMAGE NEKIRO_RUNTIME_A_IMAGE NEKIRO_RUNTIME_B_IMAGE NEKIRO_STACK_CORE_DIR NEKIRO_STACK_CONSOLE_DIR NEKIRO_STACK_SDK_GO_DIR NEKIRO_STACK_SAMPLES_DIR NEKIRO_STACK_TRANSPORT_GO_DIR; do
for name in NEKIRO_CONTROL_PLANE_IMAGE NEKIRO_A2A_ROUTER_IMAGE NEKIRO_RUNTIME_A_IMAGE NEKIRO_RUNTIME_B_IMAGE NEKIRO_NACOS_SECURE_PROXY_IMAGE NEKIRO_STACK_CORE_DIR NEKIRO_STACK_CONSOLE_DIR NEKIRO_STACK_SDK_GO_DIR NEKIRO_STACK_SAMPLES_DIR NEKIRO_STACK_TRANSPORT_GO_DIR; do
printf '%s=%s\n' "$name" "${!name}" >>"$GITHUB_ENV"
done
printf 'NEKIRO_STACK_PREPARED_ENV=%s\n' "$PREPARED_ENV" >>"$GITHUB_ENV"

- name: Generate ephemeral Nacos PKI
run: go run ./cmd/nacos-secure-fixture generate "$NEKIRO_E2E_TLS_ROOT"

- name: Start exact backend assembly
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml up --detach --wait --wait-timeout 120
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --file "$NEKIRO_E2E_COMPOSE_OVERRIDE_FILE" --profile router-nacos-secure up --detach --wait --wait-timeout 120

- name: Run trusted publication Invoke-to-Record acceptance
run: go test -tags=e2e -count=1 ./tests/backend
Expand All @@ -83,11 +106,11 @@ jobs:
- name: Capture sanitized backend logs
if: always() && steps.prepare.outcome == 'success'
shell: bash
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --profile runtime-registration --profile watch-refresh logs --no-color 2>&1 | perl scripts/sanitize-logs.pl
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --file "$NEKIRO_E2E_COMPOSE_OVERRIDE_FILE" --profile router-nacos-secure --profile runtime-registration --profile watch-refresh logs --no-color 2>&1 | perl scripts/sanitize-logs.pl

- name: Tear down backend assembly
if: always() && steps.prepare.outcome == 'success'
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --profile runtime-registration --profile watch-refresh down --volumes --remove-orphans
run: docker compose --project-name "$NEKIRO_E2E_COMPOSE_PROJECT" --file compose.yaml --file "$NEKIRO_E2E_COMPOSE_OVERRIDE_FILE" --profile router-nacos-secure --profile runtime-registration --profile watch-refresh down --volumes --remove-orphans

browser:
runs-on: ubuntu-latest
Expand All @@ -97,7 +120,18 @@ jobs:
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: NeKiro-project/NeKiro-Stack
ref: main
ref: ${{ inputs.stack_sha }}

- name: Validate exact Stack revision
shell: bash
env:
STACK_SHA: ${{ inputs.stack_sha }}
run: |
if [[ ! "$STACK_SHA" =~ ^[0-9a-f]{40}$ ]]; then
echo 'stack_sha must be one full lowercase commit SHA.' >&2
exit 1
fi
test "$(git rev-parse HEAD)" = "$STACK_SHA"

- name: Set up Go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00
Expand Down Expand Up @@ -143,7 +177,7 @@ jobs:
run: |
./scripts/prepare.sh "$NEKIRO_STACK_MANIFEST" "$WORK_ROOT" "$PREPARED_ENV"
source "$PREPARED_ENV"
for name in NEKIRO_CONTROL_PLANE_IMAGE NEKIRO_A2A_ROUTER_IMAGE NEKIRO_RUNTIME_A_IMAGE NEKIRO_RUNTIME_B_IMAGE NEKIRO_STACK_CORE_DIR NEKIRO_STACK_CONSOLE_DIR NEKIRO_STACK_SDK_GO_DIR NEKIRO_STACK_SAMPLES_DIR NEKIRO_STACK_TRANSPORT_GO_DIR; do
for name in NEKIRO_CONTROL_PLANE_IMAGE NEKIRO_A2A_ROUTER_IMAGE NEKIRO_RUNTIME_A_IMAGE NEKIRO_RUNTIME_B_IMAGE NEKIRO_NACOS_SECURE_PROXY_IMAGE NEKIRO_STACK_CORE_DIR NEKIRO_STACK_CONSOLE_DIR NEKIRO_STACK_SDK_GO_DIR NEKIRO_STACK_SAMPLES_DIR NEKIRO_STACK_TRANSPORT_GO_DIR; do
printf '%s=%s\n' "$name" "${!name}" >>"$GITHUB_ENV"
done

Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.26.0
require (
github.com/NeKiro-project/NeKiro v0.0.0-20260810110658-8c385babc9da
github.com/jackc/pgx/v5 v5.10.0
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand All @@ -14,6 +15,8 @@ require (
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.16.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
golang.org/x/sync v0.20.0 // indirect
golang.org/x/text v0.36.0 // indirect
Expand Down
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/NeKiro-project/NeKiro v0.0.0-20260810110658-8c385babc9da h1:jZSoKwcJe
github.com/NeKiro-project/NeKiro v0.0.0-20260810110658-8c385babc9da/go.mod h1:JCIEeiLu52WC/Q5QlcAKmWKRtW7CNLkZ3lV3BAn92Oo=
github.com/a2aproject/a2a-go v0.3.15 h1:h5YpCiPq3jxQ5rIns7oDjPag3ivP8u817AzdA4F+NiI=
github.com/a2aproject/a2a-go v0.3.15/go.mod h1:I7Cm+a1oL+UT6zMoP+roaRE5vdfUa1iQGVN8aSOuZ0I=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -27,12 +28,18 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0=
github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/oasdiff/yaml v0.1.1 h1:6nHx+pn9gBRM6YpBlFZFQGCCd1nuvqOBtTD3KKTgGxY=
github.com/oasdiff/yaml v0.1.1/go.mod h1:EYJNoyktvWMJ0Hmhx+6qTaqMOsalUaRGT8Sj1hNcegU=
github.com/oasdiff/yaml3 v0.0.14 h1:aLJee3hxBK2H5wdXd9iPcIXb93Nty1Ge0pT171eHtkw=
github.com/oasdiff/yaml3 v0.0.14/go.mod h1:csto2xfDjYccdUn/yw/bPjj/cYTdp6HtFA0J4TWG+gg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.16.0 h1:O9DK+vNMDVGLr2BeZqmpLeMjiMNkuXfcqntWbZV6S5g=
github.com/rogpeppe/go-internal v1.16.0/go.mod h1:DrUVZyrJU+txYW5/1kwtXQSMFio52ZOxX7yM1VHvnxs=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand All @@ -59,6 +66,8 @@ google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7E
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
92 changes: 92 additions & 0 deletions internal/workflow/core_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package workflow

import (
"os"
"strings"
"testing"

"gopkg.in/yaml.v3"
)

const (
stackRevisionExpression = "${{ inputs.stack_sha }}"
secureProxyImage = "NEKIRO_NACOS_SECURE_PROXY_IMAGE"
)

type coreIntegrationWorkflow struct {
On struct {
WorkflowCall workflowTrigger `yaml:"workflow_call"`
Dispatch workflowTrigger `yaml:"workflow_dispatch"`
} `yaml:"on"`
Jobs map[string]workflowJob `yaml:"jobs"`
}

type workflowTrigger struct {
Inputs map[string]workflowInput `yaml:"inputs"`
}

type workflowInput struct {
Required bool `yaml:"required"`
}

type workflowJob struct {
Steps []workflowStep `yaml:"steps"`
}

type workflowStep struct {
Name string `yaml:"name"`
With map[string]string `yaml:"with"`
Run string `yaml:"run"`
}

func TestCoreIntegrationPinsStackSourceAndExportsPreparedImages(t *testing.T) {
content, err := os.ReadFile("../../.github/workflows/core-integration.yml")
if err != nil {
t.Fatal(err)
}
var workflow coreIntegrationWorkflow
if err := yaml.Unmarshal(content, &workflow); err != nil {
t.Fatal(err)
}
for triggerName, trigger := range map[string]workflowTrigger{
"workflow_call": workflow.On.WorkflowCall,
"workflow_dispatch": workflow.On.Dispatch,
} {
if !trigger.Inputs["stack_sha"].Required {
t.Errorf("%s stack_sha input must be required", triggerName)
}
}
for _, jobName := range []string{"backend", "browser"} {
job, ok := workflow.Jobs[jobName]
if !ok {
t.Fatalf("missing %s job", jobName)
}
checkout := namedStep(t, job.Steps, "Check out canonical Stack")
if checkout.With["ref"] != stackRevisionExpression {
t.Errorf("%s checkout ref = %q, want exact stack_sha input", jobName, checkout.With["ref"])
}
prepare := namedStep(t, job.Steps, "Resolve exact components and build images")
if !strings.Contains(prepare.Run, secureProxyImage) {
t.Errorf("%s prepare step does not export %s", jobName, secureProxyImage)
}
}
backend := workflow.Jobs["backend"]
namedStep(t, backend.Steps, "Generate ephemeral Nacos PKI")
start := namedStep(t, backend.Steps, "Start exact backend assembly")
for _, required := range []string{"NEKIRO_E2E_COMPOSE_OVERRIDE_FILE", "--profile router-nacos-secure"} {
if !strings.Contains(start.Run, required) {
t.Errorf("backend start step does not contain %q", required)
}
}
}

func namedStep(t *testing.T, steps []workflowStep, name string) workflowStep {
t.Helper()
for _, step := range steps {
if step.Name == name {
return step
}
}
t.Fatalf("missing workflow step %q", name)
return workflowStep{}
}
Loading