Repository navigation
fix: cache the parse cache kapi 1.2 writes, not retired paths #98
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: Test | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| # Daily canary: the action installs from neokapi/neokapi releases, so it can | |
| # break without a commit here (a renamed release asset did exactly that for | |
| # 1.2.0). The schedule catches that class of breakage; the prerelease job | |
| # below catches it while it is still an RC. | |
| schedule: | |
| - cron: "17 5 * * *" | |
| workflow_dispatch: | |
| env: | |
| # The state cache jobs need kapi 1.2, the first release that keeps its state | |
| # under .kapi/work/. | |
| STATE_CACHE_KAPI_VERSION: 1.2.0-rc32 | |
| jobs: | |
| test-latest: | |
| name: "Latest (${{ matrix.os }})" | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup kapi (latest) | |
| id: setup | |
| uses: ./ | |
| with: | |
| token: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| - name: Verify version output | |
| shell: bash | |
| env: | |
| INSTALLED_VERSION: ${{ steps.setup.outputs.version }} | |
| run: | | |
| echo "Installed version: ${INSTALLED_VERSION}" | |
| test -n "${INSTALLED_VERSION}" | |
| - name: Verify kapi is on PATH | |
| shell: bash | |
| run: kapi version | |
| test-pinned: | |
| name: "Pinned version (${{ matrix.os }})" | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Get latest version for pinned test | |
| id: version | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| # Use the action's own resolver rather than a second copy of the logic. | |
| # This step used to call `releases/latest` directly and hit exactly the | |
| # bug the action had: neokapi/neokapi publishes plugin and app releases | |
| # alongside CLI ones, so that flag lands on whichever was published last | |
| # (a plugin, today), and the pinned test then asked for version | |
| # "check-v0.1.0". | |
| run: | | |
| VERSION=$(./scripts/resolve-version.sh latest) | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| echo "Pinning to CLI version ${VERSION}" | |
| - name: Setup kapi (pinned) | |
| id: setup | |
| uses: ./ | |
| with: | |
| token: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| version: ${{ steps.version.outputs.version }} | |
| - name: Verify correct version | |
| shell: bash | |
| env: | |
| EXPECTED: ${{ steps.version.outputs.version }} | |
| ACTUAL: ${{ steps.setup.outputs.version }} | |
| run: | | |
| echo "Expected: ${EXPECTED}, Actual: ${ACTUAL}" | |
| test "${EXPECTED}" = "${ACTUAL}" | |
| # Canary against the newest CLI prerelease. Release packaging changes land | |
| # on RCs first (the kapi_ → kapi-cli_ archive rename shipped on 1.2.0-rc1), | |
| # so installing the newest prerelease here fails weeks before the same | |
| # breakage would reach a stable release and every consumer workflow. | |
| test-prerelease: | |
| name: "Prerelease canary" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Resolve newest CLI prerelease | |
| id: prerelease | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| # Same tag discipline as resolve-version.sh: only vX.Y.Z-… CLI tags, | |
| # never plugin/app tags (check-v…, asr-v…, bowrain-v…). | |
| run: | | |
| VERSION=$( | |
| gh api "repos/neokapi/neokapi/releases?per_page=100" --paginate \ | |
| --jq '.[] | select(.draft == false and .prerelease == true) | .tag_name' | | |
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-' | | |
| sed 's/^v//' | | |
| sort -V | | |
| tail -n 1 | |
| ) || true | |
| if [ -z "${VERSION}" ]; then | |
| echo "No CLI prerelease found — nothing to canary." | |
| else | |
| echo "Newest CLI prerelease: ${VERSION}" | |
| fi | |
| echo "version=${VERSION}" >> "$GITHUB_OUTPUT" | |
| - name: Setup kapi (prerelease) | |
| if: steps.prerelease.outputs.version != '' | |
| id: setup | |
| uses: ./ | |
| with: | |
| token: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| version: ${{ steps.prerelease.outputs.version }} | |
| - name: Verify kapi is on PATH | |
| if: steps.prerelease.outputs.version != '' | |
| shell: bash | |
| run: kapi version | |
| # The state cache round trip on a kapi 1.2 project. This job runs the fixture | |
| # and the action saves the cache at job end; the next job restores it. Each | |
| # job compares its run in the cached project directory with a cold run of a | |
| # pristine copy, and the comparison covers every command's exit code and | |
| # output and every file the project holds afterwards. | |
| test-state-cache-save: | |
| name: "State cache save (${{ matrix.os }})" | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # kapi 1.2 prereleases publish no Windows CLI build. | |
| os: [ubuntu-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup kapi | |
| uses: ./ | |
| with: | |
| token: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| version: ${{ env.STATE_CACHE_KAPI_VERSION }} | |
| plugins: "" | |
| project-dir: test/fixture | |
| - name: Run the fixture and a cold copy | |
| shell: bash | |
| run: | | |
| test/state-cache/cold-copy.sh "${RUNNER_TEMP}/cold" | |
| test/state-cache/run.sh test/fixture "${RUNNER_TEMP}/results/cached" | |
| test/state-cache/run.sh "${RUNNER_TEMP}/cold/test/fixture" "${RUNNER_TEMP}/results/cold" | |
| test/state-cache/compare.sh "${RUNNER_TEMP}/results/cold" "${RUNNER_TEMP}/results/cached" | |
| # The restore job needs something to restore; this fails first if kapi | |
| # stops writing the path the action caches. | |
| - name: Require the parse cache kapi writes | |
| shell: bash | |
| run: | | |
| test -s test/fixture/.kapi/work/cache/docs/index.db | |
| cp test/fixture/.kapi/work/store.db "${RUNNER_TEMP}/results/store.db" | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: state-cache-save-${{ matrix.os }} | |
| path: ${{ runner.temp }}/results | |
| test-state-cache-restore: | |
| name: "State cache restore (${{ matrix.os }})" | |
| needs: test-state-cache-save | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup kapi | |
| uses: ./ | |
| with: | |
| token: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| version: ${{ env.STATE_CACHE_KAPI_VERSION }} | |
| plugins: "" | |
| project-dir: test/fixture | |
| - name: Require the restored parse cache | |
| shell: bash | |
| run: | | |
| docs=test/fixture/.kapi/work/cache/docs | |
| test -s "${docs}/index.db" | |
| ls "${docs}"/parts-*.log > /dev/null | |
| echo "Restored $(find "${docs}" -type f | wc -l | tr -d ' ') files into ${docs}" | |
| cp -R "${docs}" "${RUNNER_TEMP}/restored-docs" | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| name: state-cache-save-${{ matrix.os }} | |
| path: ${{ runner.temp }}/saved | |
| - name: A warm run matches a cold run | |
| shell: bash | |
| run: | | |
| test/state-cache/cold-copy.sh "${RUNNER_TEMP}/cold" | |
| test/state-cache/run.sh test/fixture "${RUNNER_TEMP}/results/warm" | |
| test/state-cache/run.sh "${RUNNER_TEMP}/cold/test/fixture" "${RUNNER_TEMP}/results/cold" | |
| test -s "${RUNNER_TEMP}/results/warm/docs-before.txt" | |
| test/state-cache/compare.sh "${RUNNER_TEMP}/results/cold" "${RUNNER_TEMP}/results/warm" | |
| test/state-cache/compare.sh "${RUNNER_TEMP}/saved/cold" "${RUNNER_TEMP}/results/warm" | |
| - name: A cache saved before a source change does not hide it | |
| shell: bash | |
| run: | | |
| git clean -fdxq test/fixture | |
| git checkout -- test/fixture | |
| mkdir -p test/fixture/.kapi/work/cache | |
| cp -R "${RUNNER_TEMP}/restored-docs" test/fixture/.kapi/work/cache/docs | |
| test/state-cache/change-source.sh test/fixture | |
| test/state-cache/cold-copy.sh "${RUNNER_TEMP}/cold-changed" | |
| test/state-cache/change-source.sh "${RUNNER_TEMP}/cold-changed/test/fixture" | |
| test/state-cache/run.sh test/fixture "${RUNNER_TEMP}/results/warm-changed" | |
| test/state-cache/run.sh "${RUNNER_TEMP}/cold-changed/test/fixture" "${RUNNER_TEMP}/results/cold-changed" | |
| test/state-cache/compare.sh "${RUNNER_TEMP}/results/cold-changed" "${RUNNER_TEMP}/results/warm-changed" | |
| # The negative control: .kapi/work/store.db holds stored targets and the | |
| # unit working set, so restoring it has to change a result. If the | |
| # comparison reports no difference here, it cannot be trusted above. | |
| - name: The comparison catches a restored store | |
| shell: bash | |
| run: | | |
| git clean -fdxq test/fixture | |
| git checkout -- test/fixture | |
| mkdir -p test/fixture/.kapi/work/cache | |
| cp -R "${RUNNER_TEMP}/restored-docs" test/fixture/.kapi/work/cache/docs | |
| cp "${RUNNER_TEMP}/saved/store.db" test/fixture/.kapi/work/store.db | |
| test/state-cache/run.sh test/fixture "${RUNNER_TEMP}/results/warm-store" | |
| if test/state-cache/compare.sh "${RUNNER_TEMP}/results/cold" "${RUNNER_TEMP}/results/warm-store"; then | |
| echo "::error::Restoring .kapi/work/store.db changed no result, so the comparison cannot detect restored state." | |
| exit 1 | |
| fi | |
| - uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: state-cache-restore-${{ matrix.os }} | |
| path: ${{ runner.temp }}/results | |
| test-cache: | |
| name: "Cache hit (${{ matrix.os }})" | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| # First install — populates cache | |
| - name: Setup kapi (first) | |
| uses: ./ | |
| with: | |
| token: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| # Second install — should hit cache | |
| - name: Setup kapi (cached) | |
| uses: ./ | |
| with: | |
| token: ${{ secrets.NEOKAPI_GITHUB_TOKEN }} | |
| - name: Verify kapi works from cache | |
| shell: bash | |
| run: kapi version |