Skip to content

[TT-15971]Add cross-repo dashboard build workflow for API tests#7517

Closed
jeffy-mathew wants to merge 22 commits intomasterfrom
feat/TT-15971/cross-repo-dashboard-build
Closed

[TT-15971]Add cross-repo dashboard build workflow for API tests#7517
jeffy-mathew wants to merge 22 commits intomasterfrom
feat/TT-15971/cross-repo-dashboard-build

Conversation

@jeffy-mathew
Copy link
Copy Markdown
Contributor

@jeffy-mathew jeffy-mathew commented Nov 6, 2025

Summary

This PR implements intelligent dashboard image resolution for API tests, enabling tests to run even when no matching tyk-analytics branch exists.

Changes

New Jobs Added

1. resolve-dashboard-image

Determines which dashboard image to use based on multiple criteria:

  • Strategy 1 (no-relevant-changes): If PR has no changes in relevant packages (pkg, apidef, lib, common, certs, log, config, test, user, header), use gromit default
  • Strategy 2 (gromit-branch): If matching branch exists in tyk-analytics, use gromit policy matching
  • Strategy 3 (ecr-image): If ECR image exists with commit SHA, reuse existing image
  • Strategy 4 (build-required): Build dashboard from target branch with PR gateway ref

2. build-dashboard-image (Conditional)

Only runs when needs_build=true:

  • Checks out tyk-analytics on target branch
  • Updates gateway dependency to PR commit SHA
  • Builds dashboard binary with goreleaser
  • Builds and pushes Docker image to ECR

Modified Jobs

api-tests

  • Added dependency on resolve-dashboard-image
  • Updated env-up action to use branch feat/TT-15971/add-dashboard-image-input
  • Passes resolved dashboard image to env-up action

Benefits

PRs without matching dashboard branches can now build custom dashboard automatically
Reuses existing ECR images when available (faster CI)
Smart package detection - only builds when changes affect relevant packages
Backward compatible - existing workflows continue to work unchanged
No false positives - workflow/docs/test-only changes don't trigger builds

Testing Strategy

The workflow intelligently handles different scenarios:

  1. PR with matching tyk-analytics branch → Uses gromit policy (fast ⚡)
  2. PR with no relevant package changes → Uses gromit default (fast ⚡)
  3. PR with ECR image already built → Reuses existing image (fast ⚡)
  4. PR needs custom dashboard → Builds dashboard from target branch (~10-15 min)

Related

Related to: TT-15971

Ticket Details

TT-15971
Status In Code Review
Summary Cross-Repository Dashboard Build & Testing

Generated at: 2025-11-25 16:46:32

@jeffy-mathew jeffy-mathew requested a review from a team as a code owner November 6, 2025 09:44
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Nov 6, 2025

API Changes

--- prev.txt	2025-11-17 12:18:32.071548708 +0000
+++ current.txt	2025-11-17 12:18:22.007529054 +0000
@@ -12681,10 +12681,12 @@
 
 package crypto // import "github.com/TykTechnologies/tyk/pkg/alias/crypto"
 
+Package crypto provides alias exports for internal crypto utilities.
 
 VARIABLES
 
 var (
+	// HashStr provides string hashing functionality
 	HashStr = crypto.HashStr
 )
 # Package: ./pkg/alias/gateway

@probelabs
Copy link
Copy Markdown
Contributor

probelabs Bot commented Nov 6, 2025

🔍 Code Analysis Results

This PR introduces a sophisticated CI workflow to automatically build a compatible tyk-analytics (Dashboard) Docker image for API tests. This enables testing of tyk (Gateway) pull requests that may contain breaking changes for the Dashboard, without requiring a corresponding branch in the tyk-analytics repository.

Files Changed Analysis

The vast majority of changes are in .github/workflows/release.yml (+378/-1 lines), which implements the new CI logic. The minor changes in gateway/policy.go (import reordering) and pkg/alias/crypto/crypto.go (comment addition) appear to be unrelated code cleanup.

Architecture & Impact Assessment

This PR automates on-demand, cross-repository dependency building within the CI pipeline.

  • What this PR accomplishes: It allows the api-tests to run with a custom-built Dashboard image that is compiled against the Gateway code from the PR. This solves the problem of testing breaking changes that span both repositories.
  • Key technical changes introduced:
    1. resolve-dashboard-image job: A new workflow job that intelligently determines if a custom Dashboard build is needed. It uses a multi-step strategy: checking for changes in relevant Gateway packages (pkg, apidef, etc.), checking for a matching branch in tyk-analytics, and checking for a pre-existing image in ECR for the PR.
    2. build-dashboard-image job: A new conditional job that, when triggered, checks out the tyk-analytics repository, updates its go.mod to use the Gateway code from the PR's branch, builds a new Dashboard binary, and pushes a tagged Docker image to AWS ECR.
    3. api-tests job modification: The existing api-tests job is updated to depend on the new jobs and consume the dynamically provided Dashboard image URL.
  • Affected system components: The primary impact is on the CI/CD pipeline for pull requests. It introduces a new build-time dependency on the tyk-analytics source code and a runtime dependency on AWS ECR for storing the custom-built images.

Workflow Visualization

graph TD
    A[PR Opened/Updated] --> B(goreleaser);
    B --> C[resolve-dashboard-image];

    subgraph "Image Resolution Strategy"
        C --> D{Relevant package changes?};
        D -- Yes --> J[Strategy: build-required];
        D -- No --> E{Matching branch in tyk-analytics?};
        E -- Yes --> F[Strategy: gromit-branch];
        E -- No --> G{ECR image for PR exists?};
        G -- Yes --> H[Strategy: reuse-pr-image];
        G -- No --> I[Strategy: gromit-default];
    end

    J --> K(build-dashboard-image);

    subgraph "API Testing"
        L[api-tests]
    end

    C -- image resolution info --> L;
    K -- optional built image --> L;
    F --> L;
    H --> L;
    I --> L;
Loading

Scope Discovery & Context Expansion

  • Cross-Repository Dependencies: This workflow creates a tight coupling with TykTechnologies/tyk-analytics for the build process and TykTechnologies/github-actions for the test setup action. The PR uses a feature branch (...env-up@feat/TT-15971/add-dashboard-image-input) from the github-actions repository, which must be merged and the reference updated to a commit SHA before this PR can be merged.
  • Maintenance Overhead: The hardcoded list of RELEVANT_PACKAGES in the workflow will require maintenance as the Gateway's internal structure evolves. An outdated list could lead to either unnecessary builds or, more critically, missed builds, resulting in CI failures.
  • Image Tagging Strategy: The current strategy tags images with just the PR number (e.g., tyk-7517). This is not immutable; if a PR is updated with new commits, the tag remains the same, potentially causing tests to run against a stale Dashboard image. A more robust strategy would include the commit SHA in the tag to ensure test runs are deterministic.
Metadata
  • Review Effort: 4 / 5
  • Primary Label: enhancement

Powered by Visor from Probelabs

Last updated: 2025-11-17T12:19:49.608Z | Triggered by: synchronize | Commit: 64eff4c

💡 TIP: You can chat with Visor using /visor ask <your question>

@probelabs
Copy link
Copy Markdown
Contributor

probelabs Bot commented Nov 6, 2025

🔍 Code Analysis Results

Security Issues (3)

Severity Location Issue
🔴 Critical .github/workflows/release.yml:252-255
The `go get` and `go mod edit` commands in the `build-dashboard-image` job use the `GATEWAY_BRANCH` environment variable (from `github.head_ref`) without quoting. This allows for command injection if a pull request is submitted with a specially crafted branch name containing shell metacharacters (e.g., `feature/fix-$(whoami)`). An attacker could execute arbitrary commands on the runner, potentially exposing secrets like `ORG_GH_TOKEN`.
💡 SuggestionAlways quote variables that contain user-controllable content when used in shell commands to prevent shell expansion and command injection.
🔧 Suggested Fix
          go get "github.com/TykTechnologies/tyk@$GATEWAY_BRANCH"
      # Update replace directive if present
      go mod edit -replace &#34;github.com/TykTechnologies/tyk=github.com/TykTechnologies/tyk@$GATEWAY_BRANCH&#34;</code></pre>
🔴 Critical .github/workflows/release.yml:104
The `git ls-remote` command in the `check_branch` step uses the `BRANCH` variable (derived from `github.head_ref`) without quoting. This allows for command injection if a pull request is submitted with a specially crafted branch name containing shell metacharacters. An attacker could execute arbitrary commands on the runner.
💡 SuggestionAlways quote variables that contain user-controllable content when used in shell commands to prevent shell expansion.
🔧 Suggested Fix
          if git ls-remote --heads https://$GITHUB_TOKEN@github.com/TykTechnologies/tyk-analytics.git "refs/heads/$BRANCH" | grep -q .; then
🟠 Error .github/workflows/release.yml:310
The `docker run` command uses the `--privileged` flag, which gives the container root capabilities on the host machine. This is a significant security risk, especially since a secret (`ORG_GH_TOKEN`) is passed to the container. If the build process within the container is compromised, an attacker could escape the container, compromise the runner, and steal secrets.
💡 SuggestionRemove the `--privileged` flag. If specific capabilities are required for the build, grant them explicitly with `--cap-add`. The `docker/setup-qemu-action` should handle requirements for multi-platform builds without needing privileged containers.

Architecture Issues (2)

Severity Location Issue
🟡 Warning .github/workflows/release.yml:304-512
The workflow contains several long and complex inline shell scripts, particularly in the `resolve-dashboard-image` job. Embedding complex logic directly in the YAML makes it difficult to read, test, and maintain, especially for the multi-stage decision logic in the `resolve` step.
💡 SuggestionExtract the shell script logic from steps like `check_changes`, `check_branch`, `check_ecr`, and `resolve` into separate, executable script files within the repository (e.g., in a `.github/scripts/` directory). The workflow steps can then invoke these scripts. This will make the workflow YAML significantly cleaner, and the logic becomes more modular, reusable, and easier to test independently.
🟡 Warning .github/workflows/release.yml:514
The logic for detecting the machine architecture is duplicated within the `build-dashboard-image` job. The step "Build dashboard packages for current architecture" determines `GOARCH`, and the later step "Detect platform for Docker build" determines `PLATFORM` using the exact same `case` statement on `uname -m`.
💡 SuggestionConsolidate the architecture detection into a single setup step at the beginning of the `build-dashboard-image` job. This step can determine the architecture and set both `GOARCH` and `PLATFORM` variables as outputs. Subsequent steps can then consume these outputs, removing the duplication and adhering to the Don't Repeat Yourself (DRY) principle.

✅ Performance Check Passed

No performance issues found – changes LGTM.

Quality Issues (4)

Severity Location Issue
🟠 Error .github/workflows/release.yml:552
The `GATEWAY_BRANCH` environment variable is set to `github.head_ref`, which resolves to the source branch name in a pull request. Using a mutable branch name for a dependency can lead to non-reproducible builds, as the branch can be updated while the workflow is running. This could result in building the dashboard against a different gateway commit than the one that triggered the workflow. The pull request description also states the intent is to use the 'PR commit SHA', which this implementation does not do.
💡 SuggestionTo ensure builds are deterministic and reproducible, use the immutable commit SHA of the pull request's head. Modify the environment variable to use `github.event.pull_request.head.sha` and rename it to reflect that it's a commit, not a branch (e.g., `GATEWAY_COMMIT`). Then, update the script to use this new variable.
🟢 Info .github/workflows/release.yml:598-668
The shell script logic to detect the runner's architecture (`x86_64` or `aarch64`) and determine the corresponding platform string is duplicated in two separate steps: 'Build dashboard packages for current architecture' (starts line 598) and 'Detect platform for Docker build' (starts line 653).
💡 SuggestionTo adhere to the DRY (Don't Repeat Yourself) principle, consolidate this logic into a single setup step at the beginning of the `build-dashboard-image` job. This step can export the `GOARCH` and Docker `PLATFORM` values as job outputs, which can then be consumed by the subsequent build steps, improving maintainability.
🟢 Info .github/workflows/release.yml:479
The workflow logic contains a hardcoded check against the `master` branch name to determine the build strategy. If the repository's default branch is ever renamed (e.g., to `main`), this check will become outdated and require a manual update.
💡 SuggestionTo make the workflow more resilient to future changes, consider comparing against the repository's default branch dynamically using the `github.repository.default_branch` context variable. For example: `if [ "${{ github.base_ref }}" != "${{ github.repository.default_branch }}" ]; then`.
🟡 Warning .github/workflows/release.yml:327
The command to detect changed files (`git diff ... 2>/dev/null || echo ""`) suppresses all errors from `git diff` and forces the step to succeed with an empty output. This can mask underlying issues, such as a failure to fetch the base branch, causing the workflow to incorrectly determine that no relevant files have changed. This could lead to a required dashboard build being silently skipped.
💡 SuggestionRemove the error suppression (`2>/dev/null || echo ""`) to allow the step to fail fast if `git diff` encounters a legitimate error. This will make the workflow more robust and prevent silent failures.

✅ Dependency Check Passed

No dependency issues found – changes LGTM.

✅ Connectivity Check Passed

No connectivity issues found – changes LGTM.


Powered by Visor from Probelabs

Last updated: 2025-11-17T12:19:50.856Z | Triggered by: synchronize | Commit: 64eff4c

💡 TIP: You can chat with Visor using /visor ask <your question>

@jeffy-mathew jeffy-mathew changed the title Add cross-repo dashboard build workflow for API tests [TT-15971]Add cross-repo dashboard build workflow for API tests Nov 10, 2025
@jeffy-mathew jeffy-mathew force-pushed the feat/TT-15971/cross-repo-dashboard-build branch 4 times, most recently from 372b4e9 to 501114d Compare November 13, 2025 09:05
This change implements intelligent dashboard image resolution for API tests,
enabling tests to run even when no matching tyk-analytics branch exists.

New jobs added:
1. resolve-dashboard-image: Determines which dashboard image to use
   - Strategy 1: Use gromit policy if matching branch exists (no override)
   - Strategy 2: Use existing ECR image if available
   - Strategy 3: Build dashboard from target branch with PR gateway ref

2. build-dashboard-image: Conditionally builds dashboard (only when needed)
   - Checks out tyk-analytics on target branch
   - Updates gateway dependency to PR commit SHA
   - Builds dashboard binary with goreleaser
   - Pushes Docker image to ECR

Changes to api-tests job:
- Added dependency on resolve-dashboard-image
- Updated env-up action to use new branch with dashboard_image input
- Passes resolved dashboard image to env-up action

This enables:
- PRs without matching dashboard branches to build custom dashboard
- Reuse of existing ECR images when available
- Backward compatible with existing workflows

Related: TT-15971
Only trigger custom dashboard builds when changes affect relevant packages
that could impact dashboard compatibility.

Changes:
- Add checkout step to resolve-dashboard-image job
- Add check_changes step to detect changes in specified packages:
  pkg, apidef, lib, common, certs, log, config, test, user, header
- Update resolve logic with new strategy: no-relevant-changes
- If no relevant changes detected, always use gromit default
- This avoids unnecessary dashboard builds for unrelated changes

This optimization ensures:
- Faster CI for PRs that don't affect dashboard
- Dashboard builds only when truly needed
- No false positives for workflow/docs/test-only changes
Minor documentation improvement to test cross-repo dashboard build workflow.
This change in the pkg/ directory should trigger the package change detection
and test the dashboard build logic.
Ensure base commits/refs are fetched before running git diff:
- For PR events: Fetch base SHA explicitly
- For push events: Fetch base ref explicitly
- Use two-dot syntax for PR diffs (more reliable with fetched commits)
- Add error handling to prevent workflow failures

Related: TT-15971
Add build-dashboard-image to api-tests dependencies with conditional
execution. The api-tests job will now wait for the build to complete
(or be skipped) before starting.

This ensures that when a custom dashboard build is needed, the tests
don't start until the image is available in ECR.

Related: TT-15971
Add go mod edit -replace to update the replace directive in go.mod
after updating the gateway dependency. This is needed because
tyk-analytics uses a replace directive for the tyk dependency.

Related: TT-15971
Changes:
- Check only latest commit for package changes (not full PR diff)
- Use tyk-<pr-number> tagging instead of sha-<commit>
- Update gateway dependency using branch name instead of commit SHA
- Reorder resolution strategy:
  1. Matching branch in tyk-analytics → use gromit
  2. Latest commit has changes → build new image
  3. PR image exists and no changes → reuse image
  4. Fallback to gromit default

This avoids commit SHA availability issues and simplifies image management.
Each PR gets one reusable image tag that's rebuilt when relevant packages change.

Related: TT-15971
Add base branch check to ensure custom dashboard builds only run
for PRs targeting master. For PRs targeting release branches or
other branches, always use gromit default.

This prevents unnecessary custom builds and ensures release branches
follow their normal workflow.

Related: TT-15971
Use correct build context (dist) and Dockerfile (ci/Dockerfile.distroless)
for dashboard image build, matching the tyk-analytics release workflow.

Add BUILD_PACKAGE_NAME build arg to specify tyk-dashboard package.

Related: TT-15971
Change from 'goreleaser build --single-target' to 'goreleaser release --skip=sign,docker'
to build complete .deb packages for all platforms (amd64, arm64) needed for Docker multi-platform build.

Also update golang-cross version to 1.24-bookworm to match tyk-analytics.

Related: TT-15971
Detect runner architecture dynamically and build only for that platform:
- Auto-detect x86_64 (amd64) or aarch64 (arm64)
- Pass GOARCH to goreleaser with --single-target flag
- Build Docker image for single platform only

This is faster and sufficient for CI testing since tests run on
the same architecture as the build.

Related: TT-15971
- Add ref parameter to checkout PR head SHA explicitly
- Add git log debug output to verify commit exists
- Add comment to HashStr to trigger package change detection
…mmit

- Check all commits in the current push (github.event.before..github.sha)
- Handles first push by comparing against base branch (when before is null SHA)
- More efficient: only rebuilds if new commits have relevant changes
- Reuses PR image if no new relevant changes in current push
- Use github.event.pull_request.head.sha for AFTER_SHA
- GitHub Actions creates temporary merge commits for pull_request events
- This job only runs on PRs so no fallback needed
- Compare PR against base branch instead of tracking individual pushes
- Simpler and more reliable than trying to track push commit ranges
- May rebuild on pushes without new pkg changes, but ensures correctness
- Docker layer caching will make rebuilds fast when nothing changed
- --single-target only works with 'goreleaser build', not 'release'
- GOOS and GOARCH env vars already limit the build to current platform
- Goreleaser will respect the environment variables
- Use DASHBOARD_DEPENDENCY_PACKAGES repository variable
- Fallback to default list if variable not set
- Allows changing packages without modifying workflow file
@jeffy-mathew jeffy-mathew force-pushed the feat/TT-15971/cross-repo-dashboard-build branch from 6ef3686 to 64eff4c Compare November 17, 2025 12:17
@sonarqubecloud
Copy link
Copy Markdown

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant