Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
36c74db
Initial code
anish-sahoo Jul 9, 2026
699adf3
feat: productionize cog playground
anish-sahoo Jul 12, 2026
25f3178
fix: make mise lock compatible with CI
anish-sahoo Jul 12, 2026
d9729f2
fix: enable playground webhooks in Linux CI
anish-sahoo Jul 12, 2026
b533758
fix: harden playground connection handling
anish-sahoo Jul 12, 2026
484c145
ci: move playground e2e to follow-up
anish-sahoo Jul 12, 2026
14a07d2
feat: improve playground editing and output
anish-sahoo Jul 12, 2026
95e25bc
refactor: move playground e2e to follow-up
anish-sahoo Jul 12, 2026
6fef96b
test: expand playground browser coverage
anish-sahoo Jul 12, 2026
ce72152
ci: split playground checks
anish-sahoo Jul 12, 2026
cdf73ff
fix: close stale playground event streams
anish-sahoo Jul 12, 2026
0db4bff
fix: harden playground lifecycle and accessibility
anish-sahoo Jul 12, 2026
f9ad628
feat: improve playground request and response tooling
anish-sahoo Jul 12, 2026
c277a17
docs: document playground interfaces
anish-sahoo Jul 12, 2026
953a208
Merge branch 'main' into cog-playground-beta
anish-sahoo Jul 12, 2026
7aa9dcb
fix: harden playground request and response handling
anish-sahoo Jul 13, 2026
03d45b1
test: align playground request timing assertion
anish-sahoo Jul 13, 2026
b8ce59b
refactor(playground): simplify event hub and compile validators once …
anish-sahoo Jul 13, 2026
fe9e072
Clean up implementation and ui issues
anish-sahoo Jul 13, 2026
e035e4f
default value auto-populate in form input
anish-sahoo Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ updates:
interval: "weekly"
allow:
- dependency-type: "direct"
- package-ecosystem: "npm"
directory: "/playground"
schedule:
interval: "weekly"
- package-ecosystem: "cargo"
directory: "/crates"
schedule:
Expand Down
243 changes: 214 additions & 29 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,101 @@ jobs:
steps:
- run: echo "supported_pythons=$SUPPORTED_PYTHONS"

playground-changes:
name: Detect playground changes
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
changed: ${{ steps.changes.outputs.changed }}
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Check playground sources
id: changes
env:
BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before }}
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" || -z "$BASE_SHA" || "$BASE_SHA" =~ ^0+$ ]]; then
echo "changed=true" >> "$GITHUB_OUTPUT"
elif git diff --quiet "$BASE_SHA" "$GITHUB_SHA" -- \
playground \
'pkg/cli/playground*' \
pkg/cli/root.go \
cmd/cog \
.goreleaser.yaml \
mise.toml \
mise.lock \
go.mod \
go.sum \
.github/workflows/ci.yaml \
.github/workflows/release-build.yaml; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi

fmt-playground:
name: Format playground
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
with:
version: 2026.4.27
cache_key_prefix: mise-ci-${{ github.job }}
- name: Check formatting
run: mise run fmt:playground

lint-playground:
name: Lint playground
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
with:
version: 2026.4.27
cache_key_prefix: mise-ci-${{ github.job }}
- name: Lint
run: mise run lint:playground

test-playground:
name: Test playground
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
with:
version: 2026.4.27
cache_key_prefix: mise-ci-${{ github.job }}
- name: Test
run: mise run test:playground

playground-check:
name: Check playground
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
with:
version: 2026.4.27
cache_key_prefix: mise-ci-${{ github.job }}
- name: Type check
run: mise run typecheck:playground
- name: Build embedded assets
run: mise run --force build:playground
- name: Test embedded assets
run: go test -tags playground_assets ./pkg/cli -run '^TestPlaygroundServesUI$'
- name: Upload playground assets
uses: actions/upload-artifact@v6
with:
name: PlaygroundAssets
path: pkg/cli/playground

# =============================================================================
# Version Check - Validates VERSION.txt format and sync
# =============================================================================
Expand Down Expand Up @@ -183,6 +278,7 @@ jobs:

build-cog:
name: Build cog CLI
needs: [playground-changes, playground-check]
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
Expand All @@ -193,6 +289,11 @@ jobs:
with:
version: 2026.4.27
cache_key_prefix: mise-ci-${{ github.job }}
- name: Download verified playground assets
uses: actions/download-artifact@v8
with:
name: PlaygroundAssets
path: pkg/cli/playground
- name: Get version from VERSION.txt
id: version
run: echo "version=$(tr -d '[:space:]' < VERSION.txt)" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -532,6 +633,65 @@ jobs:
- name: Test coglet-python bindings
run: uvx nox -s coglet -p ${{ matrix.python-version }}

test-playground-e2e:
name: Playground Playwright integration tests (Chromium)
needs:
- playground-changes
- fmt-playground
- lint-playground
- test-playground
- playground-check
- build-cog
- build-sdk
- build-rust
if: needs.playground-changes.outputs.changed == 'true'
runs-on: ubuntu-latest-16-cores
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Login to Docker Hub
uses: docker/login-action@v4
if: github.event.pull_request.head.repo.full_name == github.repository || github.event_name != 'pull_request'
with:
registry: index.docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Download artifacts
uses: actions/download-artifact@v8
with:
path: dist
merge-multiple: true
- name: Install cog binary
run: |
cp dist/cog ./cog
chmod +x ./cog
- uses: jdx/mise-action@v4
with:
version: 2026.4.27
cache_key_prefix: mise-ci-${{ github.job }}
- name: Install playground dependencies and Chromium
run: |
mise run playground:install
pnpm --dir playground exec playwright install --with-deps chromium
- name: Run browser integration tests
env:
BUILDKIT_PROGRESS: quiet
COG_BINARY: ${{ github.workspace }}/cog
COG_REGISTRY_HOST: ghcr.io/replicate/cog
COG_SDK_WHEEL: ${{ github.workspace }}/dist
COGLET_WHEEL: ${{ github.workspace }}/dist
run: pnpm --dir playground run test:e2e
- name: Upload browser test report
if: failure()
uses: actions/upload-artifact@v6
with:
name: PlaygroundPlaywrightReport
path: |
playground/playwright-report
playground/test-results

# Compute integration test shards dynamically.
# Slow tests (tagged with [short] skip) are distributed round-robin first,
# then remaining tests fill in. This ensures slow tests don't pile up on one runner.
Expand Down Expand Up @@ -696,6 +856,11 @@ jobs:
name: CI Complete
needs:
- setup
- playground-changes
- fmt-playground
- lint-playground
- test-playground
- playground-check
- version-check
- build-cog
- build-sdk
Expand All @@ -716,6 +881,7 @@ jobs:
- test-rust
- test-python
- test-coglet-python
- test-playground-e2e
- integration-shards
- test-integration
if: always()
Expand All @@ -725,6 +891,11 @@ jobs:
- name: Check job results
run: |
echo "Job results:"
echo " playground-changes: ${{ needs.playground-changes.result }}"
echo " fmt-playground: ${{ needs.fmt-playground.result }}"
echo " lint-playground: ${{ needs.lint-playground.result }}"
echo " test-playground: ${{ needs.test-playground.result }}"
echo " playground-check: ${{ needs.playground-check.result }}"
echo " version-check: ${{ needs.version-check.result }}"
echo " build-cog: ${{ needs.build-cog.result }}"
echo " build-sdk: ${{ needs.build-sdk.result }}"
Expand All @@ -745,41 +916,55 @@ jobs:
echo " test-rust: ${{ needs.test-rust.result }}"
echo " test-python: ${{ needs.test-python.result }}"
echo " test-coglet-python: ${{ needs.test-coglet-python.result }}"
echo " test-playground-e2e: ${{ needs.test-playground-e2e.result }}"
echo " integration-shards: ${{ needs.integration-shards.result }}"
echo " test-integration: ${{ needs.test-integration.result }}"

# Fail if any required job failed.
# lint-rust-advisories is excluded: it uses continue-on-error because
# advisory DB updates shouldn't block unrelated PRs.
FAILED=false
for result in \
"${{ needs.setup.result }}" \
"${{ needs.version-check.result }}" \
"${{ needs.build-cog.result }}" \
"${{ needs.build-sdk.result }}" \
"${{ needs.build-rust.result }}" \
"${{ needs.fmt-go.result }}" \
"${{ needs.fmt-rust.result }}" \
"${{ needs.fmt-python.result }}" \
"${{ needs.check-llm-docs.result }}" \
"${{ needs.check-stubs.result }}" \
"${{ needs.lint-go.result }}" \
"${{ needs.lint-rust.result }}" \
"${{ needs.lint-rust-deny.result }}" \
"${{ needs.lint-python.result }}" \
"${{ needs.lint-docs.result }}" \
"${{ needs.test-go.result }}" \
"${{ needs.fuzz-go.result }}" \
"${{ needs.test-rust.result }}" \
"${{ needs.test-python.result }}" \
"${{ needs.test-coglet-python.result }}" \
"${{ needs.integration-shards.result }}" \
"${{ needs.test-integration.result }}"
do
if [ "$result" = "failure" ] || [ "$result" = "cancelled" ]; then
check_success() {
if [ "$2" != "success" ]; then
echo "::error::$1 finished with unexpected result: $2"
FAILED=true
fi
done
}

# lint-rust-advisories is informational and intentionally excluded.
check_success setup "${{ needs.setup.result }}"
check_success playground-changes "${{ needs.playground-changes.result }}"
check_success fmt-playground "${{ needs.fmt-playground.result }}"
check_success lint-playground "${{ needs.lint-playground.result }}"
check_success test-playground "${{ needs.test-playground.result }}"
check_success playground-check "${{ needs.playground-check.result }}"
check_success version-check "${{ needs.version-check.result }}"
check_success build-cog "${{ needs.build-cog.result }}"
check_success build-sdk "${{ needs.build-sdk.result }}"
check_success build-rust "${{ needs.build-rust.result }}"
check_success fmt-go "${{ needs.fmt-go.result }}"
check_success fmt-rust "${{ needs.fmt-rust.result }}"
check_success fmt-python "${{ needs.fmt-python.result }}"
check_success check-llm-docs "${{ needs.check-llm-docs.result }}"
check_success check-stubs "${{ needs.check-stubs.result }}"
check_success lint-go "${{ needs.lint-go.result }}"
check_success lint-rust "${{ needs.lint-rust.result }}"
check_success lint-rust-deny "${{ needs.lint-rust-deny.result }}"
check_success lint-python "${{ needs.lint-python.result }}"
check_success lint-docs "${{ needs.lint-docs.result }}"
check_success test-go "${{ needs.test-go.result }}"
check_success fuzz-go "${{ needs.fuzz-go.result }}"
check_success test-rust "${{ needs.test-rust.result }}"
check_success test-python "${{ needs.test-python.result }}"
check_success test-coglet-python "${{ needs.test-coglet-python.result }}"
check_success integration-shards "${{ needs.integration-shards.result }}"
check_success test-integration "${{ needs.test-integration.result }}"

if [ "${{ needs.playground-changes.outputs.changed }}" = "true" ]; then
check_success test-playground-e2e "${{ needs.test-playground-e2e.result }}"
else
if [ "${{ needs.test-playground-e2e.result }}" != "skipped" ]; then
echo "::error::Playground integration tests should be skipped when playground sources are unchanged"
FAILED=true
fi
fi

if [ "$FAILED" = "true" ]; then
echo "::error::Some jobs failed or were cancelled"
Expand Down
31 changes: 29 additions & 2 deletions .github/workflows/release-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ on:
tags: ["v[0-9]+.[0-9]+.[0-9]+*"]

permissions:
contents: write
contents: read

env:
CARGO_TERM_COLOR: always
Expand Down Expand Up @@ -248,6 +248,25 @@ jobs:
name: sdk-dist
path: dist/*

build-playground:
name: Build playground assets
needs: verify-tag
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
- uses: jdx/mise-action@v4
with:
version: 2026.4.27
cache_key_prefix: mise-rel-${{ github.job }}
- name: Build embedded playground assets
run: mise run --force build:playground
- name: Upload playground assets
uses: actions/upload-artifact@v6
with:
name: playground-assets
path: pkg/cli/playground

build-coglet-wheels:
name: Build coglet wheel (${{ matrix.target }})
needs: verify-tag
Expand Down Expand Up @@ -298,7 +317,9 @@ jobs:

create-release:
name: Create release
needs: [verify-tag, build-sdk, build-coglet-wheels]
permissions:
contents: write
needs: [verify-tag, build-sdk, build-coglet-wheels, build-playground]
# macOS arm64 runner: native clang for darwin targets, zig for linux targets.
# CGo required for go-tree-sitter (static Python schema parser).
runs-on: macos-14
Expand Down Expand Up @@ -327,6 +348,12 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Download verified playground assets
uses: actions/download-artifact@v8
with:
name: playground-assets
path: pkg/cli/playground

# Goreleaser builds CLI binaries and creates draft release
- name: Build CLI and create draft release
uses: goreleaser/goreleaser-action@v7
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,10 @@ target

# Generated docs
/site

# Playground frontend
/playground/node_modules/
/playground/coverage/
/playground/playwright-report/
/playground/test-results/
/pkg/cli/playground/
2 changes: 2 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ linters:
- weakCond
exclusions:
generated: strict
paths:
- playground/node_modules
rules:
# Exclude some linters from running on test files
- path: '(.+)_test\.go'
Expand Down
Loading
Loading