interop.yml
1 # Interoperability Tests 2 # 3 # This workflow ensures Kubo remains compatible with the broader IPFS ecosystem. 4 # It builds Kubo from source, then runs: 5 # 6 # 1. helia-interop: Tests compatibility with Helia (JavaScript IPFS implementation) 7 # using Playwright-based tests from @helia/interop package. 8 # 9 # 2. ipfs-webui: Runs E2E tests from ipfs/ipfs-webui repository to verify 10 # the web interface works correctly with the locally built Kubo binary. 11 # 12 # Both jobs use caching to speed up repeated runs (npm dependencies, Playwright 13 # browsers, and webui build artifacts). 14 15 name: Interop 16 17 on: 18 workflow_dispatch: 19 pull_request: 20 paths-ignore: 21 - '**/*.md' 22 push: 23 branches: 24 - 'master' 25 26 concurrency: 27 group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event_name == 'push' && github.sha || github.ref }} 28 cancel-in-progress: true 29 30 defaults: 31 run: 32 shell: bash 33 34 jobs: 35 interop-prep: 36 if: github.repository == 'ipfs/kubo' || github.event_name == 'workflow_dispatch' 37 runs-on: ubuntu-latest 38 timeout-minutes: 5 39 env: 40 TEST_DOCKER: 0 41 TEST_FUSE: 0 42 TEST_VERBOSE: 1 43 GIT_PAGER: cat 44 IPFS_CHECK_RCMGR_DEFAULTS: 1 45 defaults: 46 run: 47 shell: bash 48 steps: 49 - uses: actions/checkout@v6 50 - uses: actions/setup-go@v6 51 with: 52 go-version-file: 'go.mod' 53 - run: make build 54 - uses: actions/upload-artifact@v7 55 with: 56 name: kubo 57 path: cmd/ipfs/ipfs 58 helia-interop: 59 needs: [interop-prep] 60 runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} 61 timeout-minutes: 20 62 defaults: 63 run: 64 shell: bash 65 steps: 66 - uses: actions/setup-node@v6 67 with: 68 node-version: lts/* 69 - uses: actions/download-artifact@v8 70 with: 71 name: kubo 72 path: cmd/ipfs 73 - run: chmod +x cmd/ipfs/ipfs 74 - run: sudo apt update 75 - run: sudo apt install -y libxkbcommon0 libxdamage1 libgbm1 libpango-1.0-0 libcairo2 # dependencies for playwright 76 # Cache node_modules based on latest @helia/interop version from npm registry. 77 # This ensures we always test against the latest release while still benefiting 78 # from caching when the version hasn't changed. 79 - name: Get latest @helia/interop version 80 id: helia-version 81 run: echo "version=$(npm view @helia/interop version)" >> $GITHUB_OUTPUT 82 - name: Cache helia-interop node_modules 83 uses: actions/cache@v5 84 id: helia-cache 85 with: 86 path: node_modules 87 key: ${{ runner.os }}-helia-interop-${{ steps.helia-version.outputs.version }} 88 - name: Install @helia/interop 89 if: steps.helia-cache.outputs.cache-hit != 'true' 90 run: npm install @helia/interop 91 # TODO(IPIP-499): Remove --grep --invert workaround once helia implements IPIP-499 92 # Tracking issue: https://github.com/ipfs/helia/issues/941 93 # 94 # PROVISIONAL HACK: Skip '@helia/mfs - should have the same CID after 95 # creating a file' test due to IPIP-499 changes in kubo. 96 # 97 # WHY IT FAILS: The test creates a 5-byte file in MFS on both kubo and helia, 98 # then compares the root directory CID. With kubo PR #11148, `ipfs files write` 99 # now produces raw CIDs for single-block files (matching `ipfs add --raw-leaves`), 100 # while helia uses `reduceSingleLeafToSelf: false` which keeps the dag-pb wrapper. 101 # Different file CIDs lead to different directory CIDs. 102 # 103 # We run aegir directly (instead of helia-interop binary) because only aegir 104 # supports the --grep/--invert flags needed to exclude specific tests. 105 - name: Run helia-interop tests (excluding IPIP-499 incompatible test) 106 run: npx aegir test -t node --bail -- --grep 'should have the same CID after creating a file' --invert 107 env: 108 KUBO_BINARY: ${{ github.workspace }}/cmd/ipfs/ipfs 109 working-directory: node_modules/@helia/interop 110 ipfs-webui: 111 needs: [interop-prep] 112 runs-on: ${{ fromJSON(github.repository == 'ipfs/kubo' && '["self-hosted", "linux", "x64", "2xlarge"]' || '"ubuntu-latest"') }} 113 timeout-minutes: 20 114 env: 115 NO_SANDBOX: true 116 LIBP2P_TCP_REUSEPORT: false 117 LIBP2P_ALLOW_WEAK_RSA_KEYS: 1 118 E2E_IPFSD_TYPE: go 119 GIT_PAGER: cat 120 IPFS_CHECK_RCMGR_DEFAULTS: 1 121 defaults: 122 run: 123 shell: bash 124 steps: 125 - uses: actions/download-artifact@v8 126 with: 127 name: kubo 128 path: cmd/ipfs 129 - run: chmod +x cmd/ipfs/ipfs 130 - uses: actions/checkout@v6 131 with: 132 repository: ipfs/ipfs-webui 133 path: ipfs-webui 134 - uses: actions/setup-node@v6 135 with: 136 node-version-file: 'ipfs-webui/.tool-versions' 137 - id: webui-ref 138 run: echo "ref=$(git rev-parse --short HEAD)" | tee -a $GITHUB_OUTPUT 139 working-directory: ipfs-webui 140 - id: webui-state 141 env: 142 GITHUB_TOKEN: ${{ github.token }} 143 ENDPOINT: repos/ipfs/ipfs-webui/commits/${{ steps.webui-ref.outputs.ref }}/status 144 SELECTOR: .state 145 KEY: state 146 run: gh api "$ENDPOINT" --jq "$SELECTOR" | xargs -I{} echo "$KEY={}" | tee -a $GITHUB_OUTPUT 147 # Cache node_modules based on package-lock.json 148 - name: Cache node_modules 149 uses: actions/cache@v5 150 id: node-modules-cache 151 with: 152 path: ipfs-webui/node_modules 153 key: ${{ runner.os }}-webui-node-modules-${{ hashFiles('ipfs-webui/package-lock.json') }} 154 restore-keys: | 155 ${{ runner.os }}-webui-node-modules- 156 - name: Install dependencies 157 if: steps.node-modules-cache.outputs.cache-hit != 'true' 158 run: npm ci --prefer-offline --no-audit --progress=false 159 working-directory: ipfs-webui 160 # Cache Playwright browsers 161 - name: Cache Playwright browsers 162 uses: actions/cache@v5 163 id: playwright-cache 164 with: 165 path: ~/.cache/ms-playwright 166 key: ${{ runner.os }}-playwright-${{ hashFiles('ipfs-webui/package-lock.json') }} 167 restore-keys: | 168 ${{ runner.os }}-playwright- 169 # On cache miss: download browsers and install OS dependencies 170 - name: Install Playwright with dependencies 171 if: steps.playwright-cache.outputs.cache-hit != 'true' 172 run: npx playwright install --with-deps 173 working-directory: ipfs-webui 174 # On cache hit: only ensure OS dependencies are present (fast, idempotent) 175 - name: Install Playwright OS dependencies 176 if: steps.playwright-cache.outputs.cache-hit == 'true' 177 run: npx playwright install-deps 178 working-directory: ipfs-webui 179 # Cache test build output 180 - name: Cache test build 181 uses: actions/cache@v5 182 id: test-build-cache 183 with: 184 path: ipfs-webui/build 185 key: ${{ runner.os }}-webui-build-${{ hashFiles('ipfs-webui/package-lock.json', 'ipfs-webui/src/**', 'ipfs-webui/public/**') }} 186 restore-keys: | 187 ${{ runner.os }}-webui-build- 188 - name: Build ipfs-webui@${{ steps.webui-ref.outputs.ref }} (state=${{ steps.webui-state.outputs.state }}) 189 if: steps.test-build-cache.outputs.cache-hit != 'true' 190 run: npm run test:build 191 working-directory: ipfs-webui 192 - name: Test ipfs-webui@${{ steps.webui-ref.outputs.ref }} (state=${{ steps.webui-state.outputs.state }}) E2E against the locally built Kubo binary 193 run: npm run test:e2e 194 env: 195 IPFS_GO_EXEC: ${{ github.workspace }}/cmd/ipfs/ipfs 196 working-directory: ipfs-webui 197 - name: Upload test artifacts on failure 198 if: failure() 199 uses: actions/upload-artifact@v7 200 with: 201 name: webui-test-results 202 path: ipfs-webui/test-results/ 203 retention-days: 7