|
46 | 46 | --enable-debug |
47 | 47 | validate: tests/e2e/validate-reachability.sh |
48 | 48 | setup-node: "true" |
| 49 | + # The tier-1 reachability backend intermittently returns empty |
| 50 | + # results while the CLI reports success. The probe exits 0 when |
| 51 | + # the facts file has alerted components; anything else is |
| 52 | + # retried before validation fails the job. |
| 53 | + retry-probe: bash tests/e2e/reach-facts-probe.sh tests/e2e/fixtures/simple-npm |
49 | 54 |
|
50 | 55 | - name: gitlab |
51 | 56 | args: >- |
@@ -94,17 +99,59 @@ jobs: |
94 | 99 | run: pip install uv |
95 | 100 |
|
96 | 101 | - name: Run Socket CLI |
| 102 | + id: run-cli |
97 | 103 | env: |
98 | 104 | SOCKET_SECURITY_API_KEY: ${{ secrets.SOCKET_CLI_API_TOKEN }} |
| 105 | + RETRY_PROBE: ${{ matrix.retry-probe }} |
99 | 106 | run: | |
100 | 107 | set -o pipefail |
101 | | - socketcli ${{ matrix.args }} 2>&1 | tee /tmp/e2e-output.log |
| 108 | + # Entries with retry-probe get up to 3 attempts: the probe exits 0 |
| 109 | + # when the scan output looks complete, and a run that fails it is |
| 110 | + # re-run on the assumption of a transient backend failure. A |
| 111 | + # persistent incomplete result still reaches validation. Validation |
| 112 | + # only treats the explicit zero-project backend signature as |
| 113 | + # inconclusive; any other empty result remains a failure. Retries are |
| 114 | + # surfaced as warning annotations so flake frequency stays visible. |
| 115 | + max_attempts=3 |
| 116 | + attempt=1 |
| 117 | + while :; do |
| 118 | + socketcli ${{ matrix.args }} 2>&1 | tee /tmp/e2e-output.log |
| 119 | + [ -z "$RETRY_PROBE" ] && break |
| 120 | + if bash -c "$RETRY_PROBE"; then |
| 121 | + break |
| 122 | + fi |
| 123 | + if [ "$attempt" -ge "$max_attempts" ]; then |
| 124 | + echo "::warning title=e2e-${{ matrix.name }} incomplete results::output still fails the completeness probe after ${max_attempts} attempts; letting validation classify the result" |
| 125 | + echo "diagnostics=true" >> "$GITHUB_OUTPUT" |
| 126 | + break |
| 127 | + fi |
| 128 | + echo "::warning title=e2e-${{ matrix.name }} transient retry::attempt ${attempt} failed the completeness probe (suspected backend transient); retrying" |
| 129 | + echo "e2e-${{ matrix.name }}: retry after attempt ${attempt} — completeness probe failed (suspected transient)" >> "$GITHUB_STEP_SUMMARY" |
| 130 | + attempt=$((attempt+1)) |
| 131 | + sleep 30 |
| 132 | + done |
102 | 133 |
|
103 | 134 | - name: Validate results |
104 | 135 | env: |
105 | 136 | SOCKET_SECURITY_API_KEY: ${{ secrets.SOCKET_CLI_API_TOKEN }} |
106 | 137 | run: bash ${{ matrix.validate }} |
107 | 138 |
|
| 139 | + - name: Upload diagnostics on failure |
| 140 | + if: failure() || steps.run-cli.outputs.diagnostics == 'true' |
| 141 | + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 |
| 142 | + with: |
| 143 | + name: e2e-${{ matrix.name }}-diagnostics-attempt${{ github.run_attempt }} |
| 144 | + path: | |
| 145 | + /tmp/e2e-output.log |
| 146 | + /tmp/*.sarif |
| 147 | + tests/e2e/fixtures/simple-npm/.socket.facts.json |
| 148 | + tests/e2e/fixtures/simple-pypi/.socket.facts.json |
| 149 | + gl-*.json |
| 150 | + license_output.json |
| 151 | + if-no-files-found: ignore |
| 152 | + include-hidden-files: true |
| 153 | + retention-days: 14 |
| 154 | + |
108 | 155 | # Branch protection requires the e2e-* checks, but the `e2e` job above is |
109 | 156 | # skipped on PRs that can't access repository secrets -- fork PRs and |
110 | 157 | # Dependabot PRs. A job skipped via a job-level `if` never expands its |
|
0 commit comments