name: Nix Build on: pull_request: branches: - main push: branches: - main permissions: contents: read pull-requests: write jobs: check-workspace-sync: name: Check flake.nix workspace sync runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6 - name: Check workspace sync id: check run: | set -euo pipefail if node scripts/check-nix-workspace.mjs; then echo "SYNC_OK=true" >> "$GITHUB_OUTPUT" else echo "SYNC_OK=false" >> "$GITHUB_OUTPUT" fi - name: Extract missing items if: steps.check.outputs.SYNC_OK == 'false' && github.event_name == 'pull_request' id: missing run: | { echo "body<" echo "❌ flake.nix workspace lists out of sync" echo "" echo "The recursive workspace dependencies of \`apps/kimi-code\` do not match \`flake.nix\`. Please run \`node scripts/check-nix-workspace.mjs\` locally for details." echo "" echo "Typical fix: add the missing package name to \`workspaceNames\` and its path to \`workspacePaths\` in \`flake.nix\`." echo "EOF" } >> "$GITHUB_OUTPUT" - name: Post or update PR comment if: steps.check.outputs.SYNC_OK == 'false' && github.event_name == 'pull_request' uses: actions/github-script@v7 env: COMMENT_BODY: ${{ steps.missing.outputs.body }} with: script: | const marker = ''; const body = process.env.COMMENT_BODY; const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, }); const existing = comments.find(c => c.user.login === 'github-actions[bot]' && c.body.includes(marker) ); if (existing) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body, }); } - name: Fail if workspace sync failed if: steps.check.outputs.SYNC_OK == 'false' run: exit 1 nix-build: name: nix build .#kimi-code needs: check-workspace-sync runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v6 - name: Install Nix uses: cachix/install-nix-action@v31 with: nix-path: nixpkgs=channel:nixos-unstable - name: Build id: build run: | set -euo pipefail LOG_FILE="$(mktemp)" if nix build .#kimi-code --print-build-logs 2>&1 | tee "$LOG_FILE"; then echo "BUILD_FAILED=false" >> "$GITHUB_OUTPUT" else echo "BUILD_FAILED=true" >> "$GITHUB_OUTPUT" echo "LOG_FILE=$LOG_FILE" >> "$GITHUB_OUTPUT" fi - name: Extract error log if: steps.build.outputs.BUILD_FAILED == 'true' && github.event_name == 'pull_request' id: error run: | LOG_FILE="${{ steps.build.outputs.LOG_FILE }}" # Extract hash mismatch info SPECIFIED=$(grep -oP 'specified:\s+\K\S+' "$LOG_FILE" || true) GOT=$(grep -oP 'got:\s+\K\S+' "$LOG_FILE" || true) if [ -n "$SPECIFIED" ] && [ -n "$GOT" ]; then { echo "body<> "$GITHUB_OUTPUT" else TAIL=$(tail -n 80 "$LOG_FILE" | sed 's/^/ /') { echo "body<> "$GITHUB_OUTPUT" fi - name: Post or update PR comment if: steps.build.outputs.BUILD_FAILED == 'true' && github.event_name == 'pull_request' uses: actions/github-script@v7 env: COMMENT_BODY: ${{ steps.error.outputs.body }} with: script: | const marker = ''; const body = marker + '\n' + process.env.COMMENT_BODY; const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, }); const existing = comments.find(c => c.user.login === 'github-actions[bot]' && c.body.includes(marker) ); if (existing) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body, }); } - name: Fail the job if build failed if: steps.build.outputs.BUILD_FAILED == 'true' run: exit 1