Skip to content

Split LocalStack integration tests for fork vs upstream PRs#275

Open
jhjaggars wants to merge 2 commits intoopenshift-online:mainfrom
jhjaggars:split-localstack-tests-fork-upstream
Open

Split LocalStack integration tests for fork vs upstream PRs#275
jhjaggars wants to merge 2 commits intoopenshift-online:mainfrom
jhjaggars:split-localstack-tests-fork-upstream

Conversation

@jhjaggars
Copy link
Copy Markdown
Collaborator

@jhjaggars jhjaggars commented Feb 18, 2026

User description

Summary

This PR splits the LocalStack integration tests workflow into two jobs to support fork contributors who cannot access the LOCALSTACK_AUTH_TOKEN repository secret.

Changes

1. Infrastructure Configuration

  • docker-compose.yml: Made LocalStack image configurable via LOCALSTACK_IMAGE environment variable
  • terraform/local/variables.tf: Added deploy_api variable to control API stack deployment
  • terraform/local/main.tf: Gated API/ECR resources with count = var.deploy_api ? 1 : 0
  • terraform/local/outputs.tf: Made API-related outputs conditional

2. Makefile Targets

  • Added start-community: Start LocalStack Community (no auth token required)
  • Added deploy-community: Deploy infrastructure without Lambda or API (for Community edition)

3. GitHub Workflow Split

Job 1: localstack-community (Fork PRs)

  • Condition: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository
  • Image: LocalStack Community (localstack/localstack:latest)
  • Deploy: make deploy-community (no Lambda, no API)
  • Processing: Scan mode container via make run-scan-background
  • Tests: make test-e2e-quick (API tests self-skip when endpoint is empty)
  • No Python setup needed (API not deployed)

Job 2: localstack-pro (Upstream PRs & Main)

  • Condition: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository)
  • Image: LocalStack Pro (localstack/localstack-pro:latest)
  • Deploy: make deploy-api (full stack with Lambda and API)
  • Processing: Lambda (event-driven)
  • Tests: make test-e2e-with-warmup (full test suite)
  • Includes Python setup for API builds

Benefits

  1. Fork Contributors: Can now run integration tests without LocalStack Pro subscription
  2. Upstream PRs: Continue to use full LocalStack Pro features for comprehensive testing
  3. Backward Compatible: Existing workflows and deployments continue to work unchanged
  4. Validated: Terraform configuration validated successfully

Testing

  • ✅ Terraform validation passed
  • ✅ All conditional resources properly gated
  • ✅ Outputs handle conditional resources correctly
  • Ready for CI testing with both workflows

PR Type

Enhancement


Description

  • Split LocalStack integration tests into two separate jobs for fork vs upstream PRs

  • Added LocalStack Community job for fork PRs without auth token requirement

  • Added LocalStack Pro job for upstream PRs with full feature support

  • Made LocalStack image configurable via environment variable in docker-compose

  • Added deploy_api variable to conditionally gate API/ECR resources in Terraform

  • Added Makefile targets start-community and deploy-community for Community edition


Diagram Walkthrough

flowchart LR
  PR["Pull Request Event"]
  FORK{"Fork PR?"}
  UPSTREAM["Upstream PR or Push"]
  COMMUNITY["localstack-community Job"]
  PRO["localstack-pro Job"]
  COMM_IMG["LocalStack Community Image"]
  PRO_IMG["LocalStack Pro Image"]
  COMM_DEPLOY["deploy-community: No Lambda/API"]
  PRO_DEPLOY["deploy-api: Full Stack"]
  COMM_TEST["test-e2e-quick"]
  PRO_TEST["test-e2e-with-warmup"]
  
  PR --> FORK
  FORK -->|Yes| COMMUNITY
  FORK -->|No| UPSTREAM
  UPSTREAM --> PRO
  COMMUNITY --> COMM_IMG
  PRO --> PRO_IMG
  COMM_IMG --> COMM_DEPLOY
  PRO_IMG --> PRO_DEPLOY
  COMM_DEPLOY --> COMM_TEST
  PRO_DEPLOY --> PRO_TEST
Loading

File Walkthrough

Relevant files
Configuration changes
localstack-integration-tests.yaml
Split workflow into fork and upstream jobs                             

.github/workflows/localstack-integration-tests.yaml

  • Split single localstack-integration job into two conditional jobs:
    localstack-community and localstack-pro
  • localstack-community job runs for fork PRs (when
    github.event.pull_request.head.repo.full_name != github.repository)
  • localstack-pro job runs for upstream PRs and main branch pushes
  • Community job uses make start-community and make deploy-community
    without auth token
  • Pro job uses make start and make deploy-api with LOCALSTACK_AUTH_TOKEN
    secret
  • Both jobs include comprehensive setup, deployment, testing, and
    debugging steps
+234/-6 
docker-compose.yml
Make LocalStack image configurable                                             

docker-compose.yml

  • Made LocalStack image configurable via LOCALSTACK_IMAGE environment
    variable with default fallback to localstack/localstack-pro:latest
  • Allows dynamic image selection between Community and Pro editions at
    runtime
+1/-1     
Enhancement
Makefile
Add Community edition Makefile targets                                     

Makefile

  • Added start-community target to start LocalStack Community edition
    using LOCALSTACK_IMAGE=localstack/localstack:latest
  • Added deploy-community target to deploy infrastructure without Lambda
    and API using -var="deploy_lambda=false" -var="deploy_api=false"
  • Updated .PHONY declaration to include new targets
  • Updated start target help text to specify "LocalStack Pro"
+20/-2   
variables.tf
Add deploy_api variable                                                                   

terraform/local/variables.tf

  • Added new deploy_api boolean variable (default: true) to control API
    stack deployment
  • Variable description indicates LocalStack Pro requirement for API
    features
+6/-0     
main.tf
Gate API resources on deploy_api variable                               

terraform/local/main.tf

  • Added count = var.deploy_api ? 1 : 0 to ECR repositories
    (lambda_processor, api_service, api_authorizer)
  • Added count = var.deploy_api ? 1 : 0 to all API-related IAM roles and
    policies
  • Added count = var.deploy_api ? 1 : 0 to Secrets Manager secret for API
    PSK
  • Updated Lambda function condition to count = var.deploy_lambda &&
    var.deploy_api ? 1 : 0
  • Added count = var.deploy_api ? 1 : 0 to central_api_stack module
  • Updated all references to conditional resources to use index notation
    [0]
+33/-17 
outputs.tf
Make API outputs conditional                                                         

terraform/local/outputs.tf

  • Made API-related outputs conditional on var.deploy_api variable
  • Updated outputs: api_gateway_endpoint, api_gateway_id,
    api_authorizer_function_arn, api_service_function_arn,
    api_psk_secret_name, ecr_api_service_url, ecr_api_authorizer_url
  • Updated central_lambda_function output to check both deploy_lambda &&
    deploy_api
  • Updated ecr_repository_url output to be conditional on deploy_api
  • Updated test_commands output to conditionally show API and Lambda test
    commands
+13/-13 

Fork PRs cannot access repository secrets (LOCALSTACK_AUTH_TOKEN), so this
change splits the workflow into two jobs:

- localstack-community: Uses LocalStack Community (free, no token) for fork PRs
  - Runs processor in scan mode (no Lambda/API)
  - Uses make start-community and make deploy-community

- localstack-pro: Uses LocalStack Pro (full features) for upstream PRs and main
  - Runs with Lambda containers and API Gateway
  - Uses make start and make deploy-api

Changes:
- docker-compose.yml: Make image configurable via LOCALSTACK_IMAGE env var
- terraform/local/variables.tf: Add deploy_api variable
- terraform/local/main.tf: Gate API/ECR resources on deploy_api
- terraform/local/outputs.tf: Make API outputs conditional
- Makefile: Add start-community and deploy-community targets
- .github/workflows/: Split into two jobs with different conditions

This allows fork contributors to run integration tests without LocalStack Pro
while maintaining full testing for upstream changes.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
@openshift-ci
Copy link
Copy Markdown

openshift-ci bot commented Feb 18, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jhjaggars

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Feb 18, 2026
@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Feb 18, 2026

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
CI supply chain

Description: The workflow introduces supply-chain risk by downloading kubectl via curl from a
dynamically-resolved "stable" URL without checksum/signature verification (lines 30-34)
and by using an unpinned GitHub Action reference medyagh/setup-minikube@master (lines
36-41), allowing upstream changes or a compromised distribution channel to execute
arbitrary code in CI.
localstack-integration-tests.yaml [29-41]

Referred Code
- name: Install kubectl
  run: |
    curl -LO --retry 5 --retry-delay 2 --retry-max-time 30 --retry-all-errors "https://dl.k8s.io/release/$(curl -L -s --retry 5 --retry-delay 2 --retry-max-time 30 --retry-all-errors https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
    chmod +x kubectl
    sudo mv kubectl /usr/local/bin/
    kubectl version --client

- name: Start minikube
  uses: medyagh/setup-minikube@master
  with:
    driver: docker
    kubernetes-version: v1.33.0
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Potential secret leakage: The failure-debug step prints broad system and Terraform details (e.g., terraform show,
pod/log outputs) that may inadvertently expose sensitive values depending on resource
sensitivity and runtime logs.

Referred Code
- name: Cleanup and debug (if test fails)
  if: failure()
  run: |
    echo "=== Debug Information ==="
    echo ""

    # Ensure kubectl is using minikube context
    kubectl config use-context minikube || echo "Could not set kubectl context"

    echo "Minikube status:"
    minikube status || echo "Minikube not running"
    echo ""

    echo "Docker containers:"
    docker ps -a || echo "Could not list containers"
    echo ""

    echo "LocalStack logs:"
    docker logs rosa-localstack --tail=50 2>&1 || docker-compose logs localstack --tail=50 2>&1 || echo "Could not get LocalStack logs"
    echo ""



 ... (clipped 23 lines)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Feb 18, 2026

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 52.61%. Comparing base (c1cf6db) to head (6dc7164).
⚠️ Report is 17 commits behind head on main.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

❗ There is a different number of reports uploaded between BASE (c1cf6db) and HEAD (6dc7164). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (c1cf6db) HEAD (6dc7164)
unittests 3 0
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #275       +/-   ##
===========================================
- Coverage   73.07%   52.61%   -20.47%     
===========================================
  Files           8       12        +4     
  Lines         765     1015      +250     
===========================================
- Hits          559      534       -25     
- Misses        206      456      +250     
- Partials        0       25       +25     
Flag Coverage Δ
go-unittests 52.61% <ø> (?)
unittests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Feb 18, 2026

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Refactor GitHub workflow to reduce duplication

The GitHub workflow file has two nearly identical jobs, localstack-community and
localstack-pro, causing code duplication. Refactor this using a matrix strategy
or YAML anchors to centralize shared steps, improving maintainability.

Examples:

.github/workflows/localstack-integration-tests.yaml [10-413]
  localstack-community:
    runs-on: ubuntu-latest
    name: LocalStack Community Tests (Fork PRs)
    if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Set up Go

 ... (clipped 394 lines)

Solution Walkthrough:

Before:

jobs:
  localstack-community:
    if: <fork_pr_condition>
    steps:
      - name: Setup Go
      - name: Setup Terraform
      - name: Setup Minikube
      - name: Start LocalStack Community
      - name: Deploy Community infra
      - name: Run quick tests
      - name: Debug on failure
  localstack-pro:
    if: <upstream_pr_condition>
    steps:
      - name: Setup Go
      - name: Setup Terraform
      - name: Setup Minikube
      - name: Start LocalStack Pro
      - name: Deploy Pro infra
      - name: Run full tests
      - name: Debug on failure

After:

jobs:
  localstack-tests:
    strategy:
      matrix:
        edition: [community, pro]
    if: (matrix.edition == 'community' && <fork_pr_condition>) || (matrix.edition == 'pro' && <upstream_pr_condition>)
    steps:
      - name: Setup Go
      - name: Setup Terraform
      - name: Setup Minikube
      - name: Start LocalStack
        if: matrix.edition == 'community'
        run: make start-community
      - name: Start LocalStack Pro
        if: matrix.edition == 'pro'
        run: make start
      - name: Deploy and Test
        # ... conditional steps based on matrix.edition
      - name: Debug on failure
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies significant code duplication between the localstack-community and localstack-pro jobs, which poses a long-term maintenance risk for the CI workflow.

Medium
Possible issue
Left-align Kubernetes patch YAML

Remove the leading indentation from the heredoc content for
/tmp/vector-patch.yaml. This ensures the generated file is a valid Kubernetes
patch, which would otherwise fail due to incorrect formatting.

.github/workflows/localstack-integration-tests.yaml [342-360]

         cat > /tmp/vector-patch.yaml <<EOF
-        apiVersion: apps/v1
-        kind: DaemonSet
-        metadata:
-          name: vector-logs
-          namespace: logging
-        spec:
-          template:
-            spec:
-              hostAliases:
-              - ip: "$HOST_IP"
-                hostnames:
-                - "host.docker.internal"
-              containers:
-              - name: vector
-                env:
-                - name: S3_BUCKET_NAME
-                  value: "$CENTRAL_BUCKET"
-        EOF
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  name: vector-logs
+  namespace: logging
+spec:
+  template:
+    spec:
+      hostAliases:
+      - ip: "$HOST_IP"
+        hostnames:
+        - "host.docker.internal"
+      containers:
+      - name: vector
+        env:
+        - name: S3_BUCKET_NAME
+          value: "$CENTRAL_BUCKET"
+EOF

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a bug where leading spaces in the heredoc would create an invalid YAML file, causing the kubectl patch command to fail and breaking the localstack-pro workflow.

Medium
General
Sync help text to background scan

Update the help text in the deploy-community Makefile target to reference make
run-scan-background instead of make run-scan to match its usage in the workflow.

Makefile [90-96]

     deploy-community: build init ## Deploy infrastructure for LocalStack Community (no Lambda, no API)
     	@echo "Deploying to LocalStack Community (no Lambda, no API)..."
     	cd terraform/local && terraform apply -auto-approve -var="deploy_lambda=false" -var="deploy_api=false"
     	@echo ""
     	@echo "✅ Infrastructure deployed! Ready for container scan mode."
     	@echo ""
-    	@echo "Run 'make run-scan' to start the processor in scan mode"
+    	@echo "Run 'make run-scan-background' to start the processor in scan mode"
  • Apply / Chat
Suggestion importance[1-10]: 4

__

Why: This suggestion correctly points out an inconsistency between the help text in the Makefile and the command used in the CI workflow, improving clarity and developer experience.

Low
  • Update

This commit simplifies the LocalStack testing approach by skipping tests
entirely for fork PRs instead of trying to support LocalStack Community
with conditional terraform resources.

Changes:
- Reverted all terraform conditional logic (deploy_api variable, count guards)
- Removed start-community and deploy-community Makefile targets
- Restored hardcoded LocalStack Pro image in docker-compose.yml
- Simplified workflow to single job that skips fork PRs via if condition
- Fixed YAML indentation in Vector patch heredoc

Fork contributors get full coverage from integration-tests.yaml (minikube
+ MinIO) which doesn't require LocalStack Pro secrets. This eliminates
maintenance burden of gating every new resource with conditionals.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. Review effort 3/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants