Security hardening: FFI integer overflow prevention, credential leakage fix, and CI/CD pinning #1774
Workflow file for this run
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: C# tests | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - release-* | |
| - v* | |
| pull_request: | |
| workflow_dispatch: | |
| inputs: | |
| full-matrix: | |
| description: "Run the full server, host, and language version matrix" | |
| type: boolean | |
| default: false | |
| name: | |
| required: false | |
| type: string | |
| description: "(Optional) Test run name" | |
| schedule: | |
| - cron: "0 3 * * *" | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: C#-${{ github.head_ref || github.ref }}-${{ toJson(inputs) }} | |
| cancel-in-progress: true | |
| run-name: | |
| # Use a distinct name for full-matrix or scheduled runs; otherwise keep manual-dispatch naming behavior | |
| ${{ (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs['full-matrix'] == 'true')) && 'C# Matrix Tests' || (github.event_name == 'workflow_dispatch' && (inputs.name == '' && format('{0} @ {1} {2}', github.ref_name, github.sha, toJson(inputs)) || inputs.name)) || '' }} | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| tests: | |
| name: net${{ matrix.dotnet }}, server ${{ matrix.server.version }}, ${{ matrix.host.TARGET }} | |
| timeout-minutes: 100 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| dotnet: ["8.0"] | |
| server: | |
| - type: "valkey" | |
| version: "9.0" | |
| host: | |
| - OS: "ubuntu" | |
| NAMED_OS: "linux" | |
| RUNNER: "ubuntu-24.04" | |
| ARCH: "x64" | |
| TARGET: "x86_64-unknown-linux-gnu" | |
| runs-on: ${{ matrix.host.RUNNER }} | |
| env: | |
| VALKEY_GLIDE_DNS_TESTS_ENABLED: "1" | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - name: Output Matrix Parameters for this job | |
| run: | | |
| echo "Job running with the following matrix configuration:" | |
| echo "${{ toJson(matrix) }}" | |
| - name: Set up dotnet ${{ matrix.dotnet }} | |
| uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 | |
| with: | |
| # install latest dotnet too to use language features | |
| dotnet-version: | | |
| 9 | |
| ${{ matrix.dotnet }} | |
| env: | |
| DOTNET_INSTALL_DIR: ~/.dotnet | |
| - name: Install shared software dependencies | |
| uses: ./.github/workflows/install-shared-dependencies | |
| with: | |
| os: ${{ matrix.host.OS }} | |
| target: ${{ matrix.host.TARGET }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| server-version: ${{ matrix.server.version }} | |
| - name: Configure DNS for tests | |
| shell: bash | |
| run: | | |
| ENTRIES="127.0.0.1 valkey.glide.test.tls.com | |
| 127.0.0.1 valkey.glide.test.no_tls.com | |
| ::1 valkey.glide.test.tls.com | |
| ::1 valkey.glide.test.no_tls.com" | |
| if [[ "${{ matrix.host.OS }}" == "windows" ]]; then | |
| echo "$ENTRIES" >> /c/Windows/System32/drivers/etc/hosts | |
| else | |
| echo "$ENTRIES" | sudo tee -a /etc/hosts | |
| fi | |
| - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| path: rust/target | |
| key: rust-${{ matrix.host.TARGET }} | |
| - name: Test dotnet ${{ matrix.dotnet }} | |
| env: | |
| AWS_ACCESS_KEY_ID: test_secret_key | |
| AWS_SECRET_ACCESS_KEY: test_access_key | |
| AWS_SESSION_TOKEN: test_session_token | |
| run: dotnet test --configuration Debug --framework net${{ matrix.dotnet }} --logger "html;LogFileName=TestReport.html" --logger "trx;LogFileName=TestResults.trx" --logger "console;verbosity=detailed" --results-directory . | |
| - name: Derive failures.json (from TRX) | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| SUMMARY_FILE=failures.json | |
| if command -v xmllint >/dev/null 2>&1 && command -v jq >/dev/null 2>&1; then | |
| FAILED_COUNT=$(xmllint --xpath "string(//Counters/@failed)" TestResults.trx 2>/dev/null || echo 0) | |
| PASSED_COUNT=$(xmllint --xpath "string(//Counters/@passed)" TestResults.trx 2>/dev/null || echo 0) | |
| TOTAL_COUNT=$(xmllint --xpath "string(//Counters/@total)" TestResults.trx 2>/dev/null || echo 0) | |
| SKIPPED_COUNT=$(xmllint --xpath "string(//Counters/@skipped)" TestResults.trx 2>/dev/null || echo 0) | |
| echo "{" > "$SUMMARY_FILE" | |
| echo " \"workflow\": \"C# tests\"," >> "$SUMMARY_FILE" | |
| echo " \"runId\": ${GITHUB_RUN_ID}," >> "$SUMMARY_FILE" | |
| echo " \"jobName\": \"net${{ matrix.dotnet }}, server ${{ matrix.server.version }}, ${{ matrix.host.TARGET }}\"," >> "$SUMMARY_FILE" | |
| echo " \"matrix\": {" >> "$SUMMARY_FILE" | |
| echo " \"dotnet\": \"${{ matrix.dotnet }}\"," >> "$SUMMARY_FILE" | |
| echo " \"server\": { \"type\": \"${{ matrix.server.type }}\", \"version\": \"${{ matrix.server.version }}\" }," >> "$SUMMARY_FILE" | |
| echo " \"host\": { \"OS\": \"${{ matrix.host.OS }}\", \"ARCH\": \"${{ matrix.host.ARCH }}\", \"RUNNER\": \"${{ matrix.host.RUNNER }}\" }" >> "$SUMMARY_FILE" | |
| echo " }," >> "$SUMMARY_FILE" | |
| echo " \"summary\": { \"total\": $TOTAL_COUNT, \"passed\": $PASSED_COUNT, \"failed\": $FAILED_COUNT, \"skipped\": $SKIPPED_COUNT }," >> "$SUMMARY_FILE" | |
| echo " \"failed\": []," >> "$SUMMARY_FILE" | |
| echo " \"links\": { \"runUrl\": \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\" }" >> "$SUMMARY_FILE" | |
| echo "}" >> "$SUMMARY_FILE" | |
| else | |
| echo '{"workflow":"C# tests","summary":{"note":"Install xmllint+jq for rich failures"}}' > "$SUMMARY_FILE" | |
| fi | |
| - name: Run coverage | |
| if: ${{ matrix.dotnet == '8.0' && contains(matrix.host.RUNNER, 'ubuntu') && matrix.host.ARCH == 'x64' && matrix.server.version == '8.1' }} | |
| uses: ./.github/workflows/run-coverage | |
| - name: Upload test reports | |
| if: always() | |
| continue-on-error: true | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: test-reports-dotnet-${{ matrix.dotnet }}-${{ matrix.server.type }}-${{ matrix.server.version }}-${{ matrix.host.OS }}-${{ matrix.host.ARCH }} | |
| path: | | |
| TestReport.html | |
| TestResults.trx | |
| failures.json | |
| valkey-glide/utils/clusters/** | |
| tests-modules: | |
| name: Module tests (Docker, net${{ matrix.dotnet }}) | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| dotnet: ["8.0"] | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - name: Set up dotnet ${{ matrix.dotnet }} | |
| uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 | |
| with: | |
| dotnet-version: | | |
| 9 | |
| ${{ matrix.dotnet }} | |
| env: | |
| DOTNET_INSTALL_DIR: ~/.dotnet | |
| - name: Install shared software dependencies | |
| uses: ./.github/workflows/install-shared-dependencies | |
| with: | |
| os: ubuntu | |
| target: x86_64-unknown-linux-gnu | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| server-version: "9.0" | |
| - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| path: rust/target | |
| key: rust-x86_64-unknown-linux-gnu | |
| - name: Run module tests against Docker servers | |
| env: | |
| standalone-endpoints: "localhost:6389" | |
| cluster-endpoints: "localhost:8001,localhost:8002,localhost:8003,localhost:8004,localhost:8005,localhost:8006" | |
| run: | | |
| dotnet test tests/Valkey.Glide.IntegrationTests/ \ | |
| --framework net${{ matrix.dotnet }} \ | |
| --filter "FullyQualifiedName~ServerModules" \ | |
| --logger "html;LogFileName=ModuleTestReport.html" \ | |
| --logger "trx;LogFileName=ModuleTestResults.trx" \ | |
| --logger "console;verbosity=detailed" \ | |
| --results-directory . | |
| - name: Derive failures.json (from TRX) | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| SUMMARY_FILE=failures.json | |
| FAILED=0; PASSED=0; TOTAL=0; SKIPPED=0 | |
| if [ -f "ModuleTestResults.trx" ] && command -v xmllint >/dev/null 2>&1; then | |
| FAILED=$(xmllint --xpath "string(//Counters/@failed)" ModuleTestResults.trx 2>/dev/null || echo 0) | |
| PASSED=$(xmllint --xpath "string(//Counters/@passed)" ModuleTestResults.trx 2>/dev/null || echo 0) | |
| TOTAL=$(xmllint --xpath "string(//Counters/@total)" ModuleTestResults.trx 2>/dev/null || echo 0) | |
| SKIPPED=$(xmllint --xpath "string(//Counters/@skipped)" ModuleTestResults.trx 2>/dev/null || echo 0) | |
| fi | |
| cat > "$SUMMARY_FILE" <<EOF | |
| { | |
| "workflow": "C# tests", | |
| "runId": ${GITHUB_RUN_ID}, | |
| "jobName": "Module tests (Docker, net${{ matrix.dotnet }})", | |
| "summary": { "total": $TOTAL, "passed": $PASSED, "failed": $FAILED, "skipped": $SKIPPED }, | |
| "failed": [], | |
| "links": { "runUrl": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" } | |
| } | |
| EOF | |
| - name: Upload test reports | |
| if: always() | |
| continue-on-error: true | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: module-test-reports-net${{ matrix.dotnet }} | |
| path: | | |
| ModuleTestReport.html | |
| ModuleTestResults.trx | |
| failures.json | |
| get-containers: | |
| runs-on: ubuntu-latest | |
| if: false | |
| outputs: | |
| server-matrix-output: ${{ steps.get-matrices.outputs.server-matrix-output }} | |
| host-matrix-output: ${{ steps.get-matrices.outputs.os-matrix-output }} | |
| version-matrix-output: ${{ steps.get-matrices.outputs.version-matrix-output }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - id: get-matrices | |
| uses: ./.github/workflows/create-test-matrices | |
| with: | |
| run-full-matrix: true | |
| tag: container | |
| tests-container: | |
| runs-on: ${{ matrix.host.RUNNER }} | |
| needs: [get-containers] | |
| timeout-minutes: 25 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| dotnet: ["8.0"] | |
| server: ${{ fromJson(needs.get-containers.outputs.server-matrix-output) }} | |
| host: ${{ fromJson(needs.get-containers.outputs.host-matrix-output) }} | |
| container: | |
| image: ${{ matrix.host.IMAGE }} | |
| options: ${{ join(' -q ', matrix.host.CONTAINER_OPTIONS) }} # adding `-q` to bypass empty options | |
| env: | |
| VALKEY_GLIDE_DNS_TESTS_ENABLED: "1" | |
| steps: | |
| - name: Install git | |
| run: | | |
| yum update | |
| yum install -y git tar findutils libicu | |
| echo IMAGE=amazonlinux:latest | sed -r 's/:/-/g' >> $GITHUB_ENV | |
| # Replace `:` in the variable otherwise it can't be used in `upload-artifact` | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| submodules: true | |
| - name: Set up dotnet ${{ matrix.dotnet }} | |
| uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 | |
| with: | |
| # install latest dotnet too to use language features | |
| dotnet-version: | | |
| 9 | |
| ${{ matrix.dotnet }} | |
| - name: Install shared software dependencies | |
| uses: ./.github/workflows/install-shared-dependencies | |
| with: | |
| os: ${{ matrix.host.OS }} | |
| target: ${{ matrix.host.TARGET }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| server-version: ${{ matrix.server.version }} | |
| - name: Configure DNS for tests | |
| shell: bash | |
| run: | | |
| ENTRIES="127.0.0.1 valkey.glide.test.tls.com | |
| 127.0.0.1 valkey.glide.test.no_tls.com | |
| ::1 valkey.glide.test.tls.com | |
| ::1 valkey.glide.test.no_tls.com" | |
| echo "$ENTRIES" | tee -a /etc/hosts | |
| - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 | |
| with: | |
| path: rust/target | |
| key: rust-${{ matrix.host.IMAGE }} | |
| - name: Test dotnet ${{ matrix.dotnet }} | |
| run: dotnet test --framework net${{ matrix.dotnet }} --logger "html;LogFileName=TestReport.html" --logger "trx;LogFileName=TestResults.trx" --logger "console;verbosity=detailed" --results-directory . | |
| - name: Derive failures.json (from TRX) | |
| if: always() | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| SUMMARY_FILE=failures.json | |
| if command -v xmllint >/dev/null 2>&1 && command -v jq >/dev/null 2>&1; then | |
| FAILED_COUNT=$(xmllint --xpath "string(//Counters/@failed)" TestResults.trx 2>/dev/null || echo 0) | |
| PASSED_COUNT=$(xmllint --xpath "string(//Counters/@passed)" TestResults.trx 2>/dev/null || echo 0) | |
| TOTAL_COUNT=$(xmllint --xpath "string(//Counters/@total)" TestResults.trx 2>/dev/null || echo 0) | |
| SKIPPED_COUNT=$(xmllint --xpath "string(//Counters/@skipped)" TestResults.trx 2>/dev/null || echo 0) | |
| echo "{" > "$SUMMARY_FILE" | |
| echo " \"workflow\": \"C# tests\"," >> "$SUMMARY_FILE" | |
| echo " \"runId\": ${GITHUB_RUN_ID}," >> "$SUMMARY_FILE" | |
| echo " \"jobName\": \"net${{ matrix.dotnet }}, server ${{ matrix.server.version }}, ${{ matrix.host.TARGET }}\"," >> "$SUMMARY_FILE" | |
| echo " \"matrix\": {" >> "$SUMMARY_FILE" | |
| echo " \"dotnet\": \"${{ matrix.dotnet }}\"," >> "$SUMMARY_FILE" | |
| echo " \"server\": { \"type\": \"${{ matrix.server.type }}\", \"version\": \"${{ matrix.server.version }}\" }," >> "$SUMMARY_FILE" | |
| echo " \"host\": { \"OS\": \"${{ matrix.host.OS }}\", \"ARCH\": \"${{ matrix.host.ARCH }}\", \"RUNNER\": \"${{ matrix.host.RUNNER }}\" }" >> "$SUMMARY_FILE" | |
| echo " }," >> "$SUMMARY_FILE" | |
| echo " \"summary\": { \"total\": $TOTAL_COUNT, \"passed\": $PASSED_COUNT, \"failed\": $FAILED_COUNT, \"skipped\": $SKIPPED_COUNT }," >> "$SUMMARY_FILE" | |
| echo " \"failed\": []," >> "$SUMMARY_FILE" | |
| echo " \"links\": { \"runUrl\": \"${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\" }" >> "$SUMMARY_FILE" | |
| echo "}" >> "$SUMMARY_FILE" | |
| else | |
| echo '{"workflow":"C# tests","summary":{"note":"Install xmllint+jq for rich failures"}}' > "$SUMMARY_FILE" | |
| fi | |
| - name: Upload test reports | |
| if: always() | |
| continue-on-error: true | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: test-reports-dotnet-${{ matrix.dotnet }}-${{ matrix.server.type }}-${{ matrix.server.version }}-${{ matrix.host.IMAGE }}-${{ matrix.host.ARCH }} | |
| path: | | |
| TestReport.html | |
| TestResults.trx | |
| failures.json | |
| valkey-glide/utils/clusters/** |