feat: Add GitHub Actions CI workflow with unit and categorized integ(AST-222) #531
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Continuous Integration Tests | |
| on: | |
| pull_request: | |
| jobs: | |
| unit-tests: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout the repository | |
| uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 #v4.0.0 | |
| - name: Set up Go version | |
| uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 #v4 | |
| with: | |
| go-version-file: go.mod | |
| - run: go version | |
| - name: go test with coverage | |
| run: | | |
| sudo chmod +x ./internal/commands/.scripts/up.sh | |
| ./internal/commands/.scripts/up.sh | |
| - name: Check if total coverage is greater then 77.7 | |
| shell: bash | |
| run: | | |
| CODE_COV=$(go tool cover -func cover.out | grep total | awk '{print substr($3, 1, length($3)-1)}') | |
| EXPECTED_CODE_COV=77.7 | |
| var=$(awk 'BEGIN{ print "'$CODE_COV'"<"'$EXPECTED_CODE_COV'" }') | |
| if [ "$var" -eq 1 ];then | |
| echo "Your code coverage is too low. Coverage precentage is: $CODE_COV" | |
| exit 1 | |
| else | |
| echo "Your code coverage test passed! Coverage precentage is: $CODE_COV" | |
| exit 0 | |
| fi | |
| integration-tests: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Group 1: Scan creation and management tests (largest group, uses getRootProject) | |
| - group: scan-create | |
| name: "Scan Creation" | |
| pattern: "^Test(CreateScan|ScanCreate|Scan_|ScanTypeApi|ValidateScanTypes|ScanGenerating|ScanWithPolicy|ScanList|ScanTimeout|ScanASCA|ExecuteASCAScan)" | |
| # Group 2: Scan operations - E2E, incremental, cancel, filters | |
| - group: scan-ops | |
| name: "Scan Operations" | |
| pattern: "^Test(ScansE2E|ScansUpdate|FastScan|LightQueries|RecommendedExclusions|IncrementalScan|BranchPrimary|CancelScan|ScanCreateInclude|ScanCreateWith|ScanCreateIgnore|ScanCreateFilter|ScanWorkflow|ScanLogs|InvalidSource|ScanShow|RequiredScan|ScaResolver|BrokenLink|PartialScan|FailedScan|RunKics|RunSca|ScanGLReport)" | |
| # Group 3: Results and reports tests (uses getRootScan - read-only) | |
| - group: results | |
| name: "Results & Reports" | |
| pattern: "^Test(Result|CodeBashing|RiskManagement)" | |
| # Group 4: PR decoration tests (uses getRootScan) | |
| - group: pr-decoration | |
| name: "PR Decoration" | |
| pattern: "^TestPR" | |
| # Group 5: Project management tests | |
| - group: projects | |
| name: "Projects" | |
| pattern: "^Test(Project|CreateEmpty|CreateAlready)" | |
| # Group 6: Predicates and BFL tests (uses getRootScan) | |
| - group: predicates | |
| name: "Predicates & BFL" | |
| pattern: "^Test(Predicate|Bfl|Triage)" | |
| # Group 7: Container-specific tests (from scan_test.go and container files) | |
| - group: containers | |
| name: "Container Tests" | |
| pattern: "^Test(Container|EmptyFolder|ImagesValidation|EdgeCase)" | |
| # Group 8: Realtime scanning tests (IaC, OSS, Secrets, ASCA) and engine tests | |
| - group: realtime | |
| name: "Realtime Scanning" | |
| pattern: "^Test(IacRealtime|OssRealtime|Secrets_Realtime|Containers_Realtime|EngineNameResolution)" | |
| # Group 9: Auth, config, tenant, root tests | |
| - group: auth-config | |
| name: "Auth & Config" | |
| pattern: "^Test(Auth|Config|Tenant|Root|Log|SetLog|FeatureFlag|RateLimit|FailProxy)" | |
| # Group 10: SCM user count tests (GitHub, GitLab, Azure, Bitbucket) | |
| - group: user-count | |
| name: "User Count" | |
| pattern: "^Test(GitHub|GitLab|Azure|Bitbucket)(UserCount|Count)" | |
| # Group 11: Misc tests (chat, import, telemetry, remediation, pre-commit, pre-receive) | |
| - group: misc | |
| name: "Miscellaneous" | |
| pattern: "^Test(Chat|Import|Learn|Telemetry|Mask|Sca?Remediation|Kics?Remediation|PreCommit|Pre_?Receive|Pre_Receive|Get)" | |
| name: Integration - ${{ matrix.name }} | |
| steps: | |
| - name: Checkout the repository | |
| uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 #v4.0.0 | |
| - name: Set up Go version | |
| uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 #v4 | |
| with: | |
| go-version-file: go.mod | |
| - run: go version | |
| - name: Go Build | |
| run: go build -o ./bin/cx ./cmd | |
| - name: Start Squid proxy | |
| run: | | |
| docker run \ | |
| --name squid \ | |
| -d \ | |
| -p 3128:3128 \ | |
| -v $(pwd)/internal/commands/.scripts/squid/squid.conf:/etc/squid/squid.conf \ | |
| -v $(pwd)/internal/commands/.scripts/squid/passwords:/etc/squid/passwords \ | |
| ubuntu/squid:5.2-22.04_beta | |
| - name: Download ScaResolver | |
| run: | | |
| wget https://sca-downloads.s3.amazonaws.com/cli/latest/ScaResolver-linux64.tar.gz | |
| tar -xzvf ScaResolver-linux64.tar.gz -C /tmp | |
| rm -rf ScaResolver-linux64.tar.gz | |
| - name: Run ${{ matrix.name }} tests | |
| shell: bash | |
| env: | |
| CX_BASE_URI: ${{ secrets.CX_BASE_URI }} | |
| CX_CLIENT_ID: ${{ secrets.CX_CLIENT_ID }} | |
| CX_CLIENT_SECRET: ${{ secrets.CX_CLIENT_SECRET }} | |
| CX_BASE_AUTH_URI: ${{ secrets.CX_BASE_AUTH_URI }} | |
| CX_AST_USERNAME: ${{ secrets.CX_AST_USERNAME }} | |
| CX_AST_PASSWORD: ${{ secrets.CX_AST_PASSWORD }} | |
| CX_APIKEY: ${{ secrets.CX_APIKEY }} | |
| CX_TENANT: ${{ secrets.CX_TENANT }} | |
| CX_SCAN_SSH_KEY: ${{ secrets.CX_SCAN_SSH_KEY }} | |
| CX_ORIGIN: "cli-tests" | |
| PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| PROXY_HOST: localhost | |
| PROXY_PORT: 3128 | |
| PROXY_USERNAME: ${{ secrets.PROXY_USER }} | |
| PROXY_PASSWORD: ${{ secrets.PROXY_PASSWORD }} | |
| PR_GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| PR_GITHUB_NAMESPACE: "checkmarx" | |
| PR_GITHUB_REPO_NAME: "ast-cli" | |
| PR_GITHUB_NUMBER: 983 | |
| PR_GITLAB_TOKEN: ${{ secrets.PR_GITLAB_TOKEN }} | |
| PR_GITLAB_NAMESPACE: ${{ secrets.PR_GITLAB_NAMESPACE }} | |
| PR_GITLAB_REPO_NAME: ${{ secrets.PR_GITLAB_REPO_NAME }} | |
| PR_GITLAB_PROJECT_ID: ${{ secrets.PR_GITLAB_PROJECT_ID }} | |
| PR_GITLAB_IID: ${{ secrets.PR_GITLAB_IID }} | |
| AZURE_ORG: ${{ secrets.AZURE_ORG }} | |
| AZURE_PROJECT: ${{ secrets.AZURE_PROJECT }} | |
| AZURE_REPOS: ${{ secrets.AZURE_REPOS }} | |
| AZURE_TOKEN: ${{ secrets.AZURE_TOKEN }} | |
| AZURE_PR_NUMBER: 1 | |
| BITBUCKET_WORKSPACE: ${{ secrets.BITBUCKET_WORKSPACE }} | |
| BITBUCKET_REPOS: ${{ secrets.BITBUCKET_REPOS }} | |
| BITBUCKET_USERNAME: ${{ secrets.BITBUCKET_USERNAME }} | |
| BITBUCKET_PASSWORD: ${{ secrets.BITBUCKET_PASSWORD }} | |
| GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} | |
| GITHUB_ACTOR: ${{ github.actor }} | |
| PR_BITBUCKET_TOKEN: ${{ secrets.PR_BITBUCKET_TOKEN }} | |
| PR_BITBUCKET_NAMESPACE: "AstSystemTest" | |
| PR_BITBUCKET_REPO_NAME: "cliIntegrationTest" | |
| PR_BITBUCKET_ID: 1 | |
| run: | | |
| set -o pipefail # Preserve exit code from go test, not tee | |
| echo "Running test group: ${{ matrix.name }}" | |
| echo "Pattern: ${{ matrix.pattern }}" | |
| # Run tests matching the pattern with coverage | |
| go test \ | |
| -tags integration \ | |
| -v \ | |
| -timeout 90m \ | |
| -run "${{ matrix.pattern }}" \ | |
| -coverpkg github.com/checkmarx/ast-cli/internal/commands,github.com/checkmarx/ast-cli/internal/services,github.com/checkmarx/ast-cli/internal/wrappers \ | |
| -coverprofile cover-${{ matrix.group }}.out \ | |
| github.com/checkmarx/ast-cli/test/integration 2>&1 | tee test_output_${{ matrix.group }}.log | |
| # Check for failed tests and rerun them once | |
| if grep -q "^--- FAIL:" test_output_${{ matrix.group }}.log; then | |
| echo "Some tests failed, attempting rerun..." | |
| FAILED_TESTS=$(grep -E "^--- FAIL: " test_output_${{ matrix.group }}.log | awk '{print $3}' | tr '\n' '|' | sed 's/|$//') | |
| if [ -n "$FAILED_TESTS" ]; then | |
| echo "Rerunning failed tests: $FAILED_TESTS" | |
| go test \ | |
| -tags integration \ | |
| -v \ | |
| -timeout 30m \ | |
| -run "^($FAILED_TESTS)$" \ | |
| -coverpkg github.com/checkmarx/ast-cli/internal/commands,github.com/checkmarx/ast-cli/internal/services,github.com/checkmarx/ast-cli/internal/wrappers \ | |
| -coverprofile cover-${{ matrix.group }}-rerun.out \ | |
| github.com/checkmarx/ast-cli/test/integration | |
| fi | |
| fi | |
| - name: Stop Squid proxy | |
| if: always() | |
| run: docker stop squid || true && docker rm squid || true | |
| - name: Upload coverage artifact | |
| uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 #v4 | |
| with: | |
| name: coverage-${{ matrix.group }} | |
| path: cover-*.out | |
| - name: Upload test logs | |
| if: always() | |
| uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 #v4 | |
| with: | |
| name: test-logs-${{ matrix.group }} | |
| path: test_output_*.log | |
| merge-coverage: | |
| runs-on: ubuntu-latest | |
| needs: integration-tests | |
| steps: | |
| - name: Checkout the repository | |
| uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 #v4.0.0 | |
| - name: Set up Go version | |
| uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 #v4 | |
| with: | |
| go-version-file: go.mod | |
| - name: Install gocovmerge | |
| run: go install github.com/wadey/gocovmerge@latest | |
| - name: Download all coverage artifacts | |
| uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 #v4 | |
| with: | |
| pattern: coverage-* | |
| path: coverage-files | |
| merge-multiple: true | |
| - name: Merge coverage files | |
| run: | | |
| echo "Merging coverage files..." | |
| ls -la coverage-files/ | |
| gocovmerge coverage-files/cover-*.out > cover.out | |
| go tool cover -html=cover.out -o coverage.html | |
| - name: Coverage report | |
| uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 #v4 | |
| with: | |
| name: ${{ runner.os }}-coverage-latest | |
| path: coverage.html | |
| - name: Check if total coverage is greater then 75 | |
| shell: bash | |
| run: | | |
| CODE_COV=$(go tool cover -func cover.out | grep total | awk '{print substr($3, 1, length($3)-1)}') | |
| EXPECTED_CODE_COV=75 | |
| var=$(awk 'BEGIN{ print "'$CODE_COV'"<"'$EXPECTED_CODE_COV'" }') | |
| if [ "$var" -eq 1 ];then | |
| echo "Your code coverage is too low. Coverage precentage is: $CODE_COV" | |
| exit 1 | |
| else | |
| echo "Your code coverage test passed! Coverage precentage is: $CODE_COV" | |
| exit 0 | |
| fi | |
| - name: Run cleandata to clean up projects | |
| env: | |
| CX_BASE_URI: ${{ secrets.CX_BASE_URI }} | |
| CX_CLIENT_ID: ${{ secrets.CX_CLIENT_ID }} | |
| CX_CLIENT_SECRET: ${{ secrets.CX_CLIENT_SECRET }} | |
| CX_BASE_AUTH_URI: ${{ secrets.CX_BASE_AUTH_URI }} | |
| CX_APIKEY: ${{ secrets.CX_APIKEY }} | |
| CX_TENANT: ${{ secrets.CX_TENANT }} | |
| run: | | |
| go test -v github.com/checkmarx/ast-cli/test/cleandata || true | |
| lint: | |
| name: lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@1e31de5234b9f8995739874a8ce0492dc87873e2 #v4.0.0 | |
| - name: Set up Go version | |
| uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 #v4 | |
| with: | |
| go-version-file: go.mod | |
| - run: go version | |
| - run: go mod tidy | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc #v3 | |
| with: | |
| skip-pkg-cache: true | |
| version: v1.64.2 | |
| args: -c .golangci.yml | |
| --timeout 5m | |
| only-new-issues: true | |
| govulncheck: | |
| runs-on: ubuntu-latest | |
| name: govulncheck | |
| steps: | |
| - id: govulncheck | |
| uses: golang/govulncheck-action@7da72f730e37eeaad891fcff0a532d27ed737cd4 #v1 | |
| continue-on-error: true | |
| with: | |
| go-version-file: go.mod | |
| go-package: ./... | |
| checkDockerImage: | |
| runs-on: ubuntu-latest | |
| name: scan Docker Image with Trivy | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@722adc63f1aa60a57ec37892e133b1d319cae598 #2.0.0 | |
| - name: Set up Docker | |
| uses: docker/setup-buildx-action@cf09c5c41b299b55c366aff30022701412eb6ab0 #v1.0.0 | |
| - name: Log in to Docker Hub | |
| uses: docker/login-action@49ed152c8eca782a232dede0303416e8f356c37b #v2 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - name: Build the project | |
| run: go build -o ./cx ./cmd | |
| - name: Build Docker image | |
| run: docker build -t ast-cli:${{ github.sha }} . | |
| - name: Run Trivy scanner without downloading DBs | |
| uses: aquasecurity/trivy-action@915b19bbe73b92a6cf82a1bc12b087c9a19a5fe2 #v0.28.0 | |
| with: | |
| scan-type: 'image' | |
| image-ref: ast-cli:${{ github.sha }} | |
| format: 'table' | |
| exit-code: '1' | |
| ignore-unfixed: true | |
| vuln-type: 'os,library' | |
| output: './trivy-image-results.txt' | |
| env: | |
| TRIVY_SKIP_JAVA_DB_UPDATE: true | |
| - name: Inspect action report | |
| if: always() | |
| shell: bash | |
| run: cat ./trivy-image-results.txt |