Repository navigation
Storage soak #16
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: Storage soak | |
| on: | |
| schedule: | |
| - cron: "17 18 * * 0" | |
| workflow_dispatch: | |
| inputs: | |
| profile: | |
| description: Custom is a short exploratory run; release requires 14,400s, 10,000 documents, and 12 reopens for Level 3 evidence | |
| required: true | |
| type: choice | |
| default: custom | |
| options: | |
| - release | |
| - custom | |
| seconds: | |
| description: Concurrent online-maintenance run time in seconds | |
| required: true | |
| default: "60" | |
| documents: | |
| description: Documents retained and fully verified after every reopen | |
| required: true | |
| default: "1000" | |
| reopens: | |
| description: Close/reopen verification phases | |
| required: true | |
| default: "3" | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: storage-soak-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| online-maintenance: | |
| name: Online maintenance and reopen | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 360 | |
| env: | |
| MELDBASE_STORAGE_SOAK_PROFILE: ${{ github.event_name == 'schedule' && 'sentinel' || inputs.profile }} | |
| MELDBASE_STORAGE_SOAK_SECONDS: ${{ github.event_name == 'schedule' && '1800' || inputs.seconds }} | |
| MELDBASE_STORAGE_SOAK_DOCUMENTS: ${{ inputs.documents || '10000' }} | |
| MELDBASE_STORAGE_SOAK_REOPENS: ${{ inputs.reopens || '12' }} | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 | |
| - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| - name: Set evidence paths | |
| run: | | |
| echo "MELDBASE_STORAGE_SOAK_RECEIPT=$RUNNER_TEMP/meldbase-storage-soak-receipt.json" >> "$GITHUB_ENV" | |
| echo "MELDBASE_DURABILITY_RECEIPT=$RUNNER_TEMP/meldbase-durability-check.json" >> "$GITHUB_ENV" | |
| echo "MELDBASE_QUALIFICATION_PACKET=$RUNNER_TEMP/meldbase-qualification-level-3.json" >> "$GITHUB_ENV" | |
| - name: Build race-enabled VCS-stamped qualification executable | |
| run: go build -race -o "$RUNNER_TEMP/meld" ./cmd/meld | |
| - name: Probe the exact soak volume with the same binary | |
| run: >- | |
| "$RUNNER_TEMP/meld" durability-check | |
| --dir "$RUNNER_TEMP" | |
| --source-revision "$GITHUB_SHA" | |
| --require-clean-source | |
| > "$MELDBASE_DURABILITY_RECEIPT" | |
| - name: Concurrent writer, shadow-index catch-up, snapshots, reclamation, and repeated recovery | |
| run: | | |
| "$RUNNER_TEMP/meld" storage-soak \ | |
| --dir "$RUNNER_TEMP" \ | |
| --out "$MELDBASE_STORAGE_SOAK_RECEIPT" \ | |
| --profile "$MELDBASE_STORAGE_SOAK_PROFILE" \ | |
| --seconds "$MELDBASE_STORAGE_SOAK_SECONDS" \ | |
| --documents "$MELDBASE_STORAGE_SOAK_DOCUMENTS" \ | |
| --reopens "$MELDBASE_STORAGE_SOAK_REOPENS" \ | |
| --source-revision "$GITHUB_SHA" \ | |
| --require-clean-source \ | |
| 2>&1 | tee "$RUNNER_TEMP/meldbase-storage-soak.log" | |
| - name: Validate versioned soak receipt | |
| run: >- | |
| jq -e ' | |
| .schemaVersion == 4 and .formatRevision == 3 and .engine == "current" and | |
| .profile == env.MELDBASE_STORAGE_SOAK_PROFILE and | |
| .sourceRevision == env.GITHUB_SHA and .buildRevision == env.GITHUB_SHA and | |
| .buildModified == false and | |
| .device > 0 and (.filesystemType | length) > 0 and | |
| (.filesystemName | length) > 0 and .blockSize > 0 and | |
| .raceEnabled == true and .completedReopens == .requestedReopens and | |
| (.phases | length) == .requestedReopens and | |
| .concurrentDurationNanos >= (.requestedSeconds * 1000000000) and | |
| .actualDurationNanos >= .concurrentDurationNanos and | |
| .writes > 0 and .snapshotReads > 0 and .indexBuildBatches > 0 and | |
| .reclamationAttempts > 0 and .freeSpaceValid == true and | |
| .semanticIndexesVerified == true and | |
| .semanticIndexBuildsVerified == true and .finalIndexBuildAbsent == true and | |
| (.finalFileSha256 | length) == 64 and | |
| (if .profile == "release" then | |
| .requestedSeconds >= 14400 and .documents >= 10000 and .requestedReopens >= 12 and | |
| .reclamationConflicts > 0 and | |
| all(.phases[]; .concurrentDurationNanos > 0 and | |
| .writes > 0 and .snapshotReads > 0 and | |
| .indexBuildBatches > 0 and .reclamationAttempts > 0) | |
| else true end) | |
| ' "$MELDBASE_STORAGE_SOAK_RECEIPT" | |
| - name: Bind release receipts into a Level 3 packet | |
| if: env.MELDBASE_STORAGE_SOAK_PROFILE == 'release' | |
| run: | | |
| "$RUNNER_TEMP/meld" qualification-check \ | |
| --source-revision "$GITHUB_SHA" \ | |
| --durability-receipt "$MELDBASE_DURABILITY_RECEIPT" \ | |
| --soak-receipt "$MELDBASE_STORAGE_SOAK_RECEIPT" \ | |
| --require-level 3 \ | |
| > "$MELDBASE_QUALIFICATION_PACKET" | |
| jq -e ' | |
| .schemaVersion == 2 and .sourceRevision == env.GITHUB_SHA and | |
| .evidenceLevel == 3 and .storageQualified == false and | |
| .rollbackProtectionQualified == false and .productionQualified == false and | |
| .passed == true and | |
| (.durabilityReceiptSha256 | length) == 64 and | |
| (.soakReceiptSha256 | length) == 64 | |
| ' "$MELDBASE_QUALIFICATION_PACKET" | |
| - name: Publish soak summary | |
| run: >- | |
| jq -r ' | |
| "### Meldbase storage soak\n" + | |
| "- source / binary: `" + (.sourceRevision // "unknown") + "` / `" + (.buildRevision // "unknown") + "`\n" + | |
| "- profile / receipt schema: " + .profile + " / " + (.schemaVersion | tostring) + "\n" + | |
| "- duration: " + ((.actualDurationNanos / 1000000000) | tostring) + " seconds\n" + | |
| "- concurrent duration: " + ((.concurrentDurationNanos / 1000000000) | tostring) + " seconds\n" + | |
| "- documents: " + (.documents | tostring) + "\n" + | |
| "- reopens: " + (.completedReopens | tostring) + "\n" + | |
| "- writes / snapshot reads / index batches: " + | |
| (.writes | tostring) + " / " + (.snapshotReads | tostring) + " / " + (.indexBuildBatches | tostring) + "\n" + | |
| "- reclamation attempts / conflicts: " + | |
| (.reclamationAttempts | tostring) + " / " + (.reclamationConflicts | tostring) + "\n" + | |
| "- shadow index semantics / final abort: " + | |
| (.semanticIndexBuildsVerified | tostring) + " / " + (.finalIndexBuildAbsent | tostring) + "\n" + | |
| "- final SHA-256: `" + .finalFileSha256 + "`" | |
| ' "$MELDBASE_STORAGE_SOAK_RECEIPT" >> "$GITHUB_STEP_SUMMARY" | |
| - name: Archive release evidence | |
| uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 | |
| with: | |
| name: storage-soak-${{ github.run_id }}-${{ github.run_attempt }} | |
| path: | | |
| ${{ runner.temp }}/meldbase-storage-soak-receipt.json | |
| ${{ runner.temp }}/meldbase-durability-check.json | |
| ${{ runner.temp }}/meldbase-qualification-level-3.json | |
| ${{ runner.temp }}/meldbase-storage-soak.log | |
| if-no-files-found: error | |
| retention-days: 90 |