Compare commits
41 Commits
main
...
v0.1.19-pt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f470b36c0 | ||
|
|
2ec90924cb | ||
|
|
d772269e69 | ||
|
|
041eb71ece | ||
|
|
648b841dcf | ||
|
|
cb5dbad59b | ||
|
|
083d73e9bb | ||
|
|
023951ff8c | ||
|
|
30697bc701 | ||
|
|
b5671044b5 | ||
|
|
4b0c3b6059 | ||
|
|
62760bc825 | ||
|
|
c64b0d3a84 | ||
|
|
3a9fae1ea4 | ||
|
|
b32c75bf87 | ||
|
|
0f13710a93 | ||
|
|
8b366bc723 | ||
|
|
15fe7828d7 | ||
|
|
11dbded9be | ||
|
|
e0199a3071 | ||
|
|
29b8f81391 | ||
|
|
cb83683209 | ||
|
|
6b67458a49 | ||
|
|
09ab3b7652 | ||
|
|
1bdfbac37e | ||
|
|
42db088534 | ||
|
|
706669754c | ||
|
|
e5b4cb0aa2 | ||
|
|
338a3b3704 | ||
|
|
434d420465 | ||
|
|
07041c1c3e | ||
|
|
5e084fed31 | ||
|
|
d238ad8475 | ||
|
|
14ce8e5e5e | ||
|
|
6fda2e84c4 | ||
|
|
27d22ec7f1 | ||
|
|
729d8f75d4 | ||
|
|
e7c72010ca | ||
|
|
9564229a8b | ||
|
|
477a5c6399 | ||
|
|
85be746bcf |
@@ -1,15 +1,12 @@
|
||||
# Node modules
|
||||
node_modules/
|
||||
**/node_modules
|
||||
.pnpm-store/
|
||||
.pnpm/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Build artifacts
|
||||
**/target/
|
||||
target/
|
||||
dist/
|
||||
build/
|
||||
*.tgz
|
||||
@@ -36,12 +33,6 @@ Thumbs.db
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
# Repo content not needed for Docker builds
|
||||
.github/
|
||||
docs/
|
||||
dev_assets/
|
||||
dev_assets_seed/
|
||||
|
||||
# Docker
|
||||
Dockerfile*
|
||||
.dockerignore
|
||||
@@ -68,4 +59,4 @@ coverage/
|
||||
|
||||
# Temporary folders
|
||||
tmp/
|
||||
temp/
|
||||
temp/
|
||||
@@ -1,163 +0,0 @@
|
||||
name: container
|
||||
# Build the self-hosted images from THIS repo and publish them to the Gitea
|
||||
# registry:
|
||||
#
|
||||
# git.lair.cafe/lair/vibe-kanban-remote crates/remote/Dockerfile :8081
|
||||
# git.lair.cafe/lair/vibe-kanban-relay crates/relay-tunnel/Dockerfile :8082
|
||||
#
|
||||
# This build used to live in lair/containers, which is for *third-party* images
|
||||
# built from someone else's source. We own this fork now, so the build belongs
|
||||
# next to the code it builds — a source change and its image are one commit.
|
||||
#
|
||||
# Both crates ship their own Dockerfile (context = repo root), so there is no
|
||||
# vendored Containerfile here. Nothing in this workflow reaches out to GitHub:
|
||||
# upstream is sunset and may disappear, and a build that asks github.com what to
|
||||
# build would disappear with it.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "crates/**"
|
||||
- "packages/**"
|
||||
- "shared/**"
|
||||
- "assets/**"
|
||||
- "patches/**"
|
||||
- "Cargo.toml"
|
||||
- "Cargo.lock"
|
||||
- "package.json"
|
||||
- "pnpm-lock.yaml"
|
||||
- "pnpm-workspace.yaml"
|
||||
- "rust-toolchain.toml"
|
||||
- ".gitea/workflows/container.yml"
|
||||
workflow_dispatch:
|
||||
|
||||
# Never let two builds race: they would fight over the :latest tags and the
|
||||
# loser's digest would win at random.
|
||||
concurrency:
|
||||
group: container
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
remote:
|
||||
runs-on:
|
||||
- metal
|
||||
- podman
|
||||
# The Rust workspace builds in release mode; from a cold cache the default
|
||||
# job timeout is not enough headroom.
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: derive image tags
|
||||
id: meta
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version=$(jq -r .version package.json)
|
||||
short=$(git rev-parse --short HEAD)
|
||||
# Immutable tag first. :latest is a convenience for humans, never a
|
||||
# deployment target -- a floating tag decides which build you are
|
||||
# running based on whenever something last pulled.
|
||||
echo "immutable=${version}-g${short}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: login to registry
|
||||
run: podman login -u ${{ gitea.actor }} -p ${{ secrets.REGISTRY_TOKEN }} git.lair.cafe
|
||||
|
||||
- name: build
|
||||
env:
|
||||
IMMUTABLE: ${{ steps.meta.outputs.immutable }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
IMAGE=git.lair.cafe/lair/vibe-kanban-remote
|
||||
# FEATURES is deliberately unset: the Dockerfile strips the private
|
||||
# billing crate only when it is empty (the self-host path), and we have
|
||||
# no access to BloopAI/vibe-kanban-private.
|
||||
#
|
||||
# VITE_RELAY_API_BASE_URL is baked into the SPA at build time and is
|
||||
# ORIGIN-RELATIVE on purpose. It is not a switch that disables the
|
||||
# relay -- leaving it empty makes Bootstrap.tsx fall back to
|
||||
# window.location.origin, which aims relay calls at the remote API,
|
||||
# which does not serve them. "/relay-api" instead means the SPA calls
|
||||
# whichever host served it, so one build works unchanged behind both
|
||||
# kanban.internal and a future public name, with no CORS and no second
|
||||
# certificate. nginx strips the prefix and forwards to the relay.
|
||||
podman build --pull=newer \
|
||||
-f crates/remote/Dockerfile \
|
||||
--build-arg VITE_RELAY_API_BASE_URL=/relay-api \
|
||||
-t "${IMAGE}:${IMMUTABLE}" \
|
||||
-t "${IMAGE}:latest" \
|
||||
.
|
||||
|
||||
- name: verify the sunset really is gone
|
||||
env:
|
||||
IMMUTABLE: ${{ steps.meta.outputs.immutable }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
IMAGE=git.lair.cafe/lair/vibe-kanban-remote
|
||||
# This fork exists because upstream replaced the board with an
|
||||
# export-only page. If a merge or a bad rebase ever reinstates it, fail
|
||||
# here rather than publish an image that greets us with a dead product.
|
||||
if podman run --rm --entrypoint sh "${IMAGE}:${IMMUTABLE}" -c \
|
||||
'grep -rlq "Project functionality has been retired" /srv/static' 2>/dev/null; then
|
||||
echo "ERROR: the sunset page is present in the built bundle."
|
||||
echo "The revert of #3387 has been lost -- refusing to publish."
|
||||
exit 1
|
||||
fi
|
||||
echo "ok: no sunset page in the bundle"
|
||||
|
||||
- name: push
|
||||
env:
|
||||
IMMUTABLE: ${{ steps.meta.outputs.immutable }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
IMAGE=git.lair.cafe/lair/vibe-kanban-remote
|
||||
podman push "${IMAGE}:${IMMUTABLE}"
|
||||
podman push "${IMAGE}:latest"
|
||||
echo "published ${IMAGE}:${IMMUTABLE} (and :latest)"
|
||||
echo
|
||||
echo "pin the quadlet to the immutable tag:"
|
||||
echo " Image=${IMAGE}:${IMMUTABLE}"
|
||||
|
||||
relay:
|
||||
runs-on:
|
||||
- metal
|
||||
- podman
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: derive image tags
|
||||
id: meta
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version=$(jq -r .version package.json)
|
||||
short=$(git rev-parse --short HEAD)
|
||||
echo "immutable=${version}-g${short}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: login to registry
|
||||
run: podman login -u ${{ gitea.actor }} -p ${{ secrets.REGISTRY_TOKEN }} git.lair.cafe
|
||||
|
||||
- name: build
|
||||
env:
|
||||
IMMUTABLE: ${{ steps.meta.outputs.immutable }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
IMAGE=git.lair.cafe/lair/vibe-kanban-relay
|
||||
# No build args: the relay takes all of its configuration from the
|
||||
# environment at runtime (DATABASE_URL, RELAY_LISTEN_ADDR and the JWT
|
||||
# secret it shares with the remote server). It has no notion of its own
|
||||
# public address, which is what makes mounting it under a path safe.
|
||||
podman build --pull=newer \
|
||||
-f crates/relay-tunnel/Dockerfile \
|
||||
-t "${IMAGE}:${IMMUTABLE}" \
|
||||
-t "${IMAGE}:latest" \
|
||||
.
|
||||
|
||||
- name: push
|
||||
env:
|
||||
IMMUTABLE: ${{ steps.meta.outputs.immutable }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
IMAGE=git.lair.cafe/lair/vibe-kanban-relay
|
||||
podman push "${IMAGE}:${IMMUTABLE}"
|
||||
podman push "${IMAGE}:latest"
|
||||
echo "published ${IMAGE}:${IMMUTABLE} (and :latest)"
|
||||
@@ -1,198 +0,0 @@
|
||||
name: host-release
|
||||
# Build the LOCAL vibe-kanban server and publish it as a signed RPM to
|
||||
# rpm.lair.cafe, so a host installs it with dnf instead of `npx vibe-kanban`.
|
||||
#
|
||||
# npx is not an option here: npx-cli resolves its download from R2_BASE_URL, a
|
||||
# placeholder substituted at npm-publish time to BloopAI's bucket, with no
|
||||
# runtime override (npx-cli/src/download.ts). That serves upstream's binary --
|
||||
# which still carries the product sunset -- from infrastructure that disappears
|
||||
# when they do.
|
||||
#
|
||||
# Convention mirrors lair/claude-desktop-package: package and publish on the
|
||||
# `rpm` runner, sign with RPM_SIGNING_KEY, rsync to oolon, createrepo under
|
||||
# flock. The compile happens first on a podman runner rather than on the rpm
|
||||
# runner, so this never depends on a host toolchain matching the pinned
|
||||
# nightly in rust-toolchain.toml.
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "crates/**"
|
||||
- "packages/local-web/**"
|
||||
- "packages/web-core/**"
|
||||
- "packages/ui/**"
|
||||
- "shared/**"
|
||||
- "Cargo.toml"
|
||||
- "Cargo.lock"
|
||||
- "rust-toolchain.toml"
|
||||
- "rpm/**"
|
||||
- ".gitea/workflows/host-release.yml"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: host-release
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on:
|
||||
- metal
|
||||
- podman
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: derive version
|
||||
id: meta
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "version=$(jq -r .version package.json)" >> "$GITHUB_OUTPUT"
|
||||
echo "commit=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: build the host binary
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# --target export writes the binary straight out of the scratch stage,
|
||||
# so nothing has to be extracted from an image afterwards.
|
||||
mkdir -p out
|
||||
podman build --pull=newer \
|
||||
-f rpm/Containerfile \
|
||||
--target export \
|
||||
--output type=local,dest=out \
|
||||
.
|
||||
test -s out/vibe-kanban
|
||||
chmod 0755 out/vibe-kanban
|
||||
file out/vibe-kanban || true
|
||||
|
||||
- name: sanity-check the binary
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# The whole point of building our own: upstream's carries the sunset.
|
||||
if grep -qa "Project functionality has been retired" out/vibe-kanban; then
|
||||
echo "ERROR: the sunset page is embedded in the host binary."
|
||||
echo "The revert of #3387 has been lost -- refusing to publish."
|
||||
exit 1
|
||||
fi
|
||||
if grep -qa "Cloud is shutting down" out/vibe-kanban; then
|
||||
echo "ERROR: the cloud-shutdown banner is embedded in the host binary."
|
||||
exit 1
|
||||
fi
|
||||
# And it must point at us, not at api.vibekanban.com.
|
||||
grep -qa "kanban.internal" out/vibe-kanban \
|
||||
|| { echo "ERROR: baked API base missing from the binary"; exit 1; }
|
||||
echo "ok: no sunset UI, lair endpoints baked in"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: host-binary
|
||||
path: out/vibe-kanban
|
||||
retention-days: 7
|
||||
|
||||
outputs:
|
||||
version: ${{ steps.meta.outputs.version }}
|
||||
commit: ${{ steps.meta.outputs.commit }}
|
||||
|
||||
package:
|
||||
needs: build
|
||||
runs-on: rpm
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
fedora_version: ["43", "44"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: host-binary
|
||||
path: bin/
|
||||
|
||||
- name: rpmbuild
|
||||
run: |
|
||||
set -euo pipefail
|
||||
find bin/ -name vibe-kanban -exec mv --target-directory=bin/ {} + 2>/dev/null || true
|
||||
mkdir -p ~/rpmbuild/SOURCES
|
||||
install -m 0755 bin/vibe-kanban ~/rpmbuild/SOURCES/vibe-kanban
|
||||
rpmbuild -bb rpm/vibe-kanban.spec \
|
||||
--define "vk_version ${{ needs.build.outputs.version }}" \
|
||||
--define "vk_commit ${{ needs.build.outputs.commit }}" \
|
||||
--define "dist .fc${{ matrix.fedora_version }}"
|
||||
ls -l ~/rpmbuild/RPMS/x86_64/
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: rpm-fc${{ matrix.fedora_version }}
|
||||
path: ~/rpmbuild/RPMS/x86_64/*.rpm
|
||||
retention-days: 7
|
||||
|
||||
publish:
|
||||
needs: package
|
||||
runs-on: rpm
|
||||
env:
|
||||
RPM_REPO_HOST: oolon.kosherinata.internal
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
fedora_version: ["43", "44"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: rpm-fc${{ matrix.fedora_version }}
|
||||
path: rpms/
|
||||
|
||||
- name: Flatten RPM artifacts
|
||||
run: |
|
||||
find rpms/ -name '*.rpm' -exec mv --target-directory=rpms/ {} +
|
||||
find rpms/ -mindepth 1 -type d -empty -delete
|
||||
|
||||
- name: Import signing key
|
||||
run: |
|
||||
echo "${{ secrets.RPM_SIGNING_KEY }}" | gpg --batch --import
|
||||
fpr=$(gpg --batch --with-colons --list-keys "${{ secrets.RPM_SIGNING_KEY_ID }}" | awk -F: '/^fpr:/ { print $10; exit }')
|
||||
echo "${fpr}:6:" | gpg --batch --import-ownertrust
|
||||
sed "s/@GPG_NAME@/${{ secrets.RPM_SIGNING_KEY_ID }}/" rpm/rpmmacros > ~/.rpmmacros
|
||||
|
||||
- name: Sign RPMs
|
||||
run: |
|
||||
for rpm in rpms/*.rpm; do
|
||||
echo "signing ${rpm}..."
|
||||
rpm --addsign "${rpm}"
|
||||
done
|
||||
|
||||
- name: Set up SSH
|
||||
run: |
|
||||
install --directory --mode 700 ~/.ssh
|
||||
echo "${RSYNC_SSH_KEY}" | install --mode 600 /dev/stdin ~/.ssh/id_ed25519
|
||||
env:
|
||||
RSYNC_SSH_KEY: ${{ secrets.RSYNC_SSH_KEY }}
|
||||
|
||||
- name: Test SSH connectivity
|
||||
run: |
|
||||
ssh -o StrictHostKeyChecking=accept-new "gitea_ci@${RPM_REPO_HOST}" exit
|
||||
|
||||
- name: Sync RPMs to repo
|
||||
run: |
|
||||
rsync \
|
||||
--archive \
|
||||
--verbose \
|
||||
--chmod D755,F644 \
|
||||
rpms/*.rpm \
|
||||
"gitea_ci@${RPM_REPO_HOST}:/var/www/rpm/fedora/${{ matrix.fedora_version }}/x86_64/"
|
||||
|
||||
- name: Update repo metadata
|
||||
run: |
|
||||
# flock guards createrepo against concurrent publishes into the
|
||||
# shared repo tree (other package repos publish here too).
|
||||
ssh "gitea_ci@${RPM_REPO_HOST}" \
|
||||
"flock /var/www/rpm/.publish.lock -c 'cd /var/www/rpm/fedora/${{ matrix.fedora_version }}/x86_64 && createrepo_c --update .'"
|
||||
|
||||
- name: Generate packages.json
|
||||
run: |
|
||||
scp rpm/generate-packages-json.py "gitea_ci@${RPM_REPO_HOST}:/tmp/"
|
||||
ssh "gitea_ci@${RPM_REPO_HOST}" \
|
||||
"flock /var/www/rpm/.publish.lock -c 'python3 /tmp/generate-packages-json.py \
|
||||
--repodata-dir /var/www/rpm/fedora/${{ matrix.fedora_version }}/x86_64/repodata \
|
||||
--output /var/www/rpm/fedora/${{ matrix.fedora_version }}/x86_64/packages.json \
|
||||
--base-url https://rpm.lair.cafe/fedora/${{ matrix.fedora_version }}/x86_64'"
|
||||
@@ -33,19 +33,19 @@ runs:
|
||||
|
||||
- name: Install Rust toolchain
|
||||
if: ${{ inputs.components == '' }}
|
||||
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: ${{ inputs.toolchain }}
|
||||
|
||||
- name: Install Rust toolchain with components
|
||||
if: ${{ inputs.components != '' }}
|
||||
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: ${{ inputs.toolchain }}
|
||||
components: ${{ inputs.components }}
|
||||
|
||||
- name: Cache Rust dependencies
|
||||
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
uses: Swatinem/rust-cache@v2
|
||||
env:
|
||||
RUST_CACHE_DEBUG: true
|
||||
with:
|
||||
|
||||
43
.github/actions/setup-jsign/action.yml
vendored
43
.github/actions/setup-jsign/action.yml
vendored
@@ -1,43 +0,0 @@
|
||||
name: 'Setup Jsign'
|
||||
description: 'Downloads and caches Jsign for cross-platform Windows code signing'
|
||||
|
||||
inputs:
|
||||
version:
|
||||
description: 'Jsign version'
|
||||
required: false
|
||||
default: '7.4'
|
||||
sha256:
|
||||
description: 'Expected SHA256 of the jar'
|
||||
required: false
|
||||
default: '2abf2ade9ea322acc2d60c24794eadc465ff9380938fca4c932d09e0b25f1c28'
|
||||
|
||||
outputs:
|
||||
jar-path:
|
||||
description: 'Path to the Jsign jar'
|
||||
value: ${{ steps.path.outputs.jar }}
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Set jar path
|
||||
id: path
|
||||
shell: bash
|
||||
run: echo "jar=${{ runner.temp }}/jsign-${{ inputs.version }}.jar" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache Jsign
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ steps.path.outputs.jar }}
|
||||
key: jsign-${{ inputs.version }}-${{ inputs.sha256 }}
|
||||
|
||||
- name: Download Jsign
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
curl -sL "https://github.com/ebourg/jsign/releases/download/${{ inputs.version }}/jsign-${{ inputs.version }}.jar" \
|
||||
-o "${{ steps.path.outputs.jar }}"
|
||||
|
||||
- name: Verify checksum
|
||||
shell: bash
|
||||
run: echo "${{ inputs.sha256 }} ${{ steps.path.outputs.jar }}" | sha256sum -c -
|
||||
2
.github/actions/setup-node/action.yml
vendored
2
.github/actions/setup-node/action.yml
vendored
@@ -11,7 +11,7 @@ runs:
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: ${{ env.PNPM_VERSION }}
|
||||
|
||||
|
||||
952
.github/workflows/pre-release.yml
vendored
Normal file
952
.github/workflows/pre-release.yml
vendored
Normal file
@@ -0,0 +1,952 @@
|
||||
name: Create GitHub Pre-Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_type:
|
||||
description: "Version bump type"
|
||||
required: true
|
||||
default: "patch"
|
||||
type: choice
|
||||
options:
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
- prerelease
|
||||
|
||||
concurrency:
|
||||
group: release-${{ github.ref_name }} # allow concurrent prerelease from different branches
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
NODE_VERSION: 22
|
||||
PNPM_VERSION: 10.13.1
|
||||
RUST_TOOLCHAIN: nightly-2025-12-04
|
||||
CARGO_XWIN_VERSION: 0.20.2
|
||||
|
||||
jobs:
|
||||
bump-version:
|
||||
runs-on: ubuntu-latest-m
|
||||
outputs:
|
||||
new_tag: ${{ steps.version.outputs.new_tag }}
|
||||
new_version: ${{ steps.version.outputs.new_version }}
|
||||
branch_suffix: ${{ steps.branch.outputs.suffix }}
|
||||
steps:
|
||||
- name: Cache cargo-edit
|
||||
uses: actions/cache@v5
|
||||
id: cache-cargo-edit
|
||||
with:
|
||||
path: ~/.cargo/bin/cargo-set-version
|
||||
key: cargo-edit-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}
|
||||
|
||||
- name: Install cargo-edit
|
||||
if: steps.cache-cargo-edit.outputs.cache-hit != 'true'
|
||||
run: cargo install cargo-edit
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
||||
|
||||
- name: setup node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Setup SSH Agent for private dependencies
|
||||
id: ssh-setup
|
||||
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
|
||||
uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.VK_PRIVATE_DEPLOY_KEY }}
|
||||
|
||||
- name: Generate branch suffix
|
||||
id: branch
|
||||
run: |
|
||||
branch_name="${{ github.ref_name }}"
|
||||
# Get last 6 characters of branch name, remove all special chars (including dashes)
|
||||
suffix=$(echo "$branch_name" | tail -c 7 | sed 's/[^a-zA-Z0-9]//g' | tr '[:upper:]' '[:lower:]')
|
||||
echo "Branch: $branch_name"
|
||||
echo "Suffix: $suffix"
|
||||
echo "suffix=$suffix" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Determine and update versions
|
||||
id: version
|
||||
run: |
|
||||
# Get the latest version from npm registry
|
||||
latest_npm_version=$(npm view vibe-kanban version 2>/dev/null || echo "0.0.0")
|
||||
echo "Latest npm version: $latest_npm_version"
|
||||
|
||||
# Get current repo version
|
||||
current_repo_version=$(node -p "require('./package.json').version")
|
||||
echo "Current repo version: $current_repo_version"
|
||||
|
||||
# Use the higher of the two versions as the base (prevents downgrade errors with cargo set-version)
|
||||
base_version=$(node -e "
|
||||
const npm = '$latest_npm_version'.split('.').map(Number);
|
||||
const repo = '$current_repo_version'.split('.').map(Number);
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if ((npm[i] || 0) > (repo[i] || 0)) { console.log('$latest_npm_version'); process.exit(); }
|
||||
if ((npm[i] || 0) < (repo[i] || 0)) { console.log('$current_repo_version'); process.exit(); }
|
||||
}
|
||||
console.log('$current_repo_version');
|
||||
")
|
||||
echo "Base version for bump: $base_version"
|
||||
|
||||
timestamp=$(date +%Y%m%d%H%M%S)
|
||||
|
||||
# Update root package.json based on base version
|
||||
if [[ "${{ github.event.inputs.version_type }}" == "prerelease" ]]; then
|
||||
# For prerelease, use current package.json version and add branch suffix
|
||||
npm version prerelease --preid="${{ steps.branch.outputs.suffix }}" --no-git-tag-version
|
||||
|
||||
new_version=$(node -p "require('./package.json').version")
|
||||
new_tag="v${new_version}.${timestamp}"
|
||||
else
|
||||
# For regular releases, use base version and bump it
|
||||
npm version $base_version --no-git-tag-version --allow-same-version
|
||||
npm version ${{ github.event.inputs.version_type }} --no-git-tag-version
|
||||
|
||||
new_version=$(node -p "require('./package.json').version")
|
||||
new_tag="v${new_version}-${timestamp}"
|
||||
fi
|
||||
|
||||
# Update npx-cli package.json to match
|
||||
cd npx-cli
|
||||
npm version $new_version --no-git-tag-version --allow-same-version
|
||||
cd ..
|
||||
|
||||
# Update web app package.json to match
|
||||
cd packages/local-web
|
||||
npm version $new_version --no-git-tag-version --allow-same-version
|
||||
cd ..
|
||||
|
||||
cargo set-version --workspace "$new_version"
|
||||
|
||||
echo "New version: $new_version"
|
||||
echo "new_version=$new_version" >> $GITHUB_OUTPUT
|
||||
echo "new_tag=$new_tag" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update remote crate lockfile
|
||||
if: ${{ steps.ssh-setup.outcome == 'success' }}
|
||||
run: cargo generate-lockfile --manifest-path crates/remote/Cargo.toml
|
||||
|
||||
- name: Stop SSH agent
|
||||
if: ${{ steps.ssh-setup.outcome == 'success' }}
|
||||
run: ssh-agent -k
|
||||
|
||||
- name: Commit changes and create tag
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add package.json pnpm-lock.yaml npx-cli/package.json packages/local-web/package.json Cargo.lock
|
||||
git add $(find . -name Cargo.toml)
|
||||
[ -f crates/remote/Cargo.lock ] && git add crates/remote/Cargo.lock || true
|
||||
git commit -m "chore: bump version to ${{ steps.version.outputs.new_version }}"
|
||||
git tag -a ${{ steps.version.outputs.new_tag }} -m "Release ${{ steps.version.outputs.new_tag }}"
|
||||
git push
|
||||
git push --tags
|
||||
|
||||
build-frontend:
|
||||
needs: bump-version
|
||||
runs-on: ubuntu-latest-x64-l
|
||||
env:
|
||||
VITE_PUBLIC_REACT_VIRTUOSO_LICENSE_KEY: ${{ secrets.PUBLIC_REACT_VIRTUOSO_LICENSE_KEY }}
|
||||
VITE_VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.bump-version.outputs.new_tag }}
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Lint frontend
|
||||
run: cd packages/local-web && npm run lint
|
||||
|
||||
- name: Type check frontend
|
||||
run: cd packages/local-web && npx tsc --noEmit
|
||||
|
||||
- name: Build frontend
|
||||
run: cd packages/local-web && npm run build
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
VITE_POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
|
||||
VITE_POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }}
|
||||
VITE_SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
|
||||
- name: Create Sentry release
|
||||
uses: getsentry/action-release@v3
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
||||
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||
with:
|
||||
release: ${{ needs.bump-version.outputs.new_version }}
|
||||
environment: production
|
||||
sourcemaps: "./packages/local-web/dist"
|
||||
ignore_missing: true
|
||||
|
||||
- name: Upload frontend artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: frontend-dist
|
||||
path: packages/local-web/dist/
|
||||
retention-days: 1
|
||||
|
||||
build-backend:
|
||||
needs: [bump-version, build-frontend]
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
# Platform matrix - keep target/name in sync with package-npx-cli job
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-unknown-linux-musl
|
||||
os: ubuntu-latest-x64-l
|
||||
name: linux-x64
|
||||
- target: aarch64-unknown-linux-musl
|
||||
os: ubuntu-latest-arm64-l
|
||||
name: linux-arm64
|
||||
- target: x86_64-pc-windows-msvc
|
||||
os: ubuntu-latest-x64-l
|
||||
name: windows-x64
|
||||
- target: x86_64-apple-darwin
|
||||
os: macos-15-xlarge
|
||||
name: macos-x64
|
||||
- target: aarch64-apple-darwin
|
||||
os: macos-15-xlarge
|
||||
name: macos-arm64
|
||||
- target: aarch64-pc-windows-msvc
|
||||
os: ubuntu-latest-x64-l
|
||||
name: windows-arm64
|
||||
env:
|
||||
CARGO_INCREMENTAL: "0"
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
SCCACHE_CACHE_SIZE: "10G"
|
||||
CARGO_HOME: ${{ github.workspace }}/.cargo
|
||||
RUSTUP_HOME: ${{ github.workspace }}/.rustup
|
||||
XWIN_CACHE_DIR: ${{ github.workspace }}/.xwin-cache
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.bump-version.outputs.new_tag }}
|
||||
|
||||
- name: Setup sccache
|
||||
uses: BloopAI/sccache-action@main
|
||||
|
||||
- name: Cache Rust toolchain
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .rustup/toolchains
|
||||
key: rust-toolchain-${{ runner.os }}-${{ matrix.target }}-${{ env.RUST_TOOLCHAIN }}
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
targets: ${{ matrix.target }}
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Install dependencies (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt-get install -y clang libclang-dev lld llvm nasm cmake ninja-build
|
||||
|
||||
if [[ "${{ matrix.target }}" == *"windows"* ]]; then
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt-get install -y clang-19 clang-tools-19 llvm-19 lld-19
|
||||
echo "/usr/lib/llvm-19/bin" >> $GITHUB_PATH
|
||||
fi
|
||||
|
||||
- name: Cache Cargo registry
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
.cargo/registry/cache
|
||||
.cargo/registry/index
|
||||
.cargo/git/db
|
||||
.cargo/bin
|
||||
.cargo/.crates.toml
|
||||
.cargo/.crates2.json
|
||||
key: cargo-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: |
|
||||
cargo-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-
|
||||
|
||||
- name: Install Zig
|
||||
if: runner.os == 'Linux' && !contains(matrix.target, 'windows')
|
||||
uses: BloopAI/setup-zig@main
|
||||
with:
|
||||
version: 0.15.2
|
||||
|
||||
- name: Install cargo zigbuild
|
||||
if: runner.os == 'Linux' && !contains(matrix.target, 'windows')
|
||||
run: cargo install --locked cargo-zigbuild --version 0.20.1
|
||||
|
||||
- name: Install cargo xwin
|
||||
if: runner.os == 'Linux' && contains(matrix.target, 'windows')
|
||||
run: cargo install --locked cargo-xwin --version ${{ env.CARGO_XWIN_VERSION }}
|
||||
|
||||
- name: Cache xwin downloads
|
||||
if: runner.os == 'Linux' && contains(matrix.target, 'windows')
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: ${{ github.workspace }}/.xwin-cache
|
||||
key: xwin-${{ runner.os }}-${{ matrix.target }}-cargo-xwin-${{ env.CARGO_XWIN_VERSION }}
|
||||
|
||||
- name: Cache target
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: target
|
||||
key: target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ github.ref_name }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-${{ github.ref_name }}-
|
||||
target-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}-${{ matrix.target }}-
|
||||
|
||||
- name: Setup cargo-sweep
|
||||
shell: bash
|
||||
run: |
|
||||
cargo install --locked cargo-sweep --version 0.8.0
|
||||
|
||||
- name: Download frontend artifact
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: frontend-dist
|
||||
path: packages/local-web/dist/
|
||||
|
||||
- name: Build backend (Linux)
|
||||
if: runner.os == 'Linux' && !contains(matrix.target, 'windows')
|
||||
run: |
|
||||
cargo zigbuild --release --target ${{ matrix.target }} -p server -p mcp -p review --bin server --bin mcp_task_server --bin review
|
||||
env:
|
||||
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
|
||||
POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }}
|
||||
VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
|
||||
- name: Build backend (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
if [[ "${{ matrix.target }}" == "x86_64-apple-darwin" ]]; then
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.12
|
||||
elif [[ "${{ matrix.target }}" == "aarch64-apple-darwin" ]]; then
|
||||
export MACOSX_DEPLOYMENT_TARGET=11.0
|
||||
fi
|
||||
cargo build --release --target ${{ matrix.target }} -p server -p mcp -p review --bin server --bin mcp_task_server --bin review
|
||||
env:
|
||||
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
|
||||
POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }}
|
||||
VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
|
||||
- name: Build backend (Windows)
|
||||
if: runner.os == 'Linux' && contains(matrix.target, 'windows')
|
||||
run: |
|
||||
if [[ "${{ matrix.target }}" == "aarch64-pc-windows-msvc" ]]; then
|
||||
# ring requires clang on arm64 windows. See https://github.com/briansmith/ring/issues/2117
|
||||
chmod +x scripts/ring-cc-wrapper.sh scripts/clang
|
||||
export PATH="${{ github.workspace }}/scripts:$PATH"
|
||||
export RING_CC=/usr/lib/llvm-19/bin/clang
|
||||
export DEFAULT_CC=clang-cl
|
||||
export CC_aarch64_pc_windows_msvc="${{ github.workspace }}/scripts/ring-cc-wrapper.sh"
|
||||
fi
|
||||
cargo xwin build --cross-compiler clang-cl --release --target ${{ matrix.target }} -p server -p mcp -p review --bin server --bin mcp_task_server --bin review
|
||||
env:
|
||||
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
|
||||
POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }}
|
||||
VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
# Avoid aws-lc-sys CMake failures when Rust's `release` profile includes debug info.
|
||||
# Without this, cmake-rs selects RelWithDebInfo and CMake fails when ASM is enabled.
|
||||
CARGO_PROFILE_RELEASE_DEBUG: 0
|
||||
|
||||
- name: Setup Sentry CLI
|
||||
uses: matbour/setup-sentry-cli@v2
|
||||
with:
|
||||
token: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
organization: ${{ secrets.SENTRY_ORG }}
|
||||
project: ${{ secrets.SENTRY_PROJECT }}
|
||||
version: 2.21.2
|
||||
|
||||
- name: Upload source maps to Sentry
|
||||
run: sentry-cli debug-files upload --include-sources target/${{ matrix.target }}/release
|
||||
|
||||
- name: Prepare binaries (non-macOS)
|
||||
if: runner.os != 'macOS'
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p dist
|
||||
if [[ "${{ matrix.name }}" == *"windows"* ]]; then
|
||||
cp target/${{ matrix.target }}/release/server.exe dist/vibe-kanban-${{ matrix.name }}.exe
|
||||
cp target/${{ matrix.target }}/release/mcp_task_server.exe dist/vibe-kanban-mcp-${{ matrix.name }}.exe
|
||||
cp target/${{ matrix.target }}/release/review.exe dist/vibe-kanban-review-${{ matrix.name }}.exe
|
||||
else
|
||||
cp target/${{ matrix.target }}/release/server dist/vibe-kanban-${{ matrix.name }}
|
||||
cp target/${{ matrix.target }}/release/mcp_task_server dist/vibe-kanban-mcp-${{ matrix.name }}
|
||||
cp target/${{ matrix.target }}/release/review dist/vibe-kanban-review-${{ matrix.name }}
|
||||
fi
|
||||
|
||||
# Code signing for macOS only
|
||||
- name: Prepare Apple certificate (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
echo "${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}" | base64 --decode > certificate.p12
|
||||
|
||||
- name: Write API Key to file
|
||||
if: runner.os == 'macOS'
|
||||
env:
|
||||
API_KEY: ${{ secrets.APP_STORE_API_KEY }}
|
||||
run: echo $API_KEY > app_store_key.json
|
||||
|
||||
- name: Sign main binary (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
uses: BloopAI/apple-code-sign-action@v1
|
||||
with:
|
||||
input_path: target/${{ matrix.target }}/release/server
|
||||
output_path: vibe-kanban
|
||||
p12_file: certificate.p12
|
||||
p12_password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
sign: true
|
||||
sign_args: "--code-signature-flags=runtime"
|
||||
|
||||
- name: Package main binary (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: zip vibe-kanban.zip vibe-kanban
|
||||
|
||||
- name: Sign MCP binary (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
uses: BloopAI/apple-code-sign-action@v1
|
||||
with:
|
||||
input_path: target/${{ matrix.target }}/release/mcp_task_server
|
||||
output_path: vibe-kanban-mcp
|
||||
p12_file: certificate.p12
|
||||
p12_password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
sign: true
|
||||
sign_args: "--code-signature-flags=runtime"
|
||||
|
||||
- name: Package MCP binary (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: zip vibe-kanban-mcp.zip vibe-kanban-mcp
|
||||
|
||||
- name: Sign Review binary (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
uses: BloopAI/apple-code-sign-action@v1
|
||||
with:
|
||||
input_path: target/${{ matrix.target }}/release/review
|
||||
output_path: vibe-kanban-review
|
||||
p12_file: certificate.p12
|
||||
p12_password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
sign: true
|
||||
sign_args: "--code-signature-flags=runtime"
|
||||
|
||||
- name: Package Review binary (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: zip vibe-kanban-review.zip vibe-kanban-review
|
||||
|
||||
- name: Notarize signed binaries (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
uses: BloopAI/apple-code-sign-action@main
|
||||
continue-on-error: true
|
||||
with:
|
||||
input_path: |
|
||||
vibe-kanban.zip
|
||||
vibe-kanban-mcp.zip
|
||||
vibe-kanban-review.zip
|
||||
sign: false
|
||||
notarize: true
|
||||
app_store_connect_api_key_json_file: app_store_key.json
|
||||
|
||||
- name: Prepare signed binaries (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
mkdir -p dist
|
||||
cp vibe-kanban.zip dist/vibe-kanban-${{ matrix.name }}.zip
|
||||
cp vibe-kanban-mcp.zip dist/vibe-kanban-mcp-${{ matrix.name }}.zip
|
||||
cp vibe-kanban-review.zip dist/vibe-kanban-review-${{ matrix.name }}.zip
|
||||
|
||||
- name: Clean up certificates (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
rm -f certificate.p12
|
||||
rm -rf private_keys/
|
||||
|
||||
- name: Upload binary artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: backend-binary-${{ matrix.name }}
|
||||
path: dist/
|
||||
retention-days: 1
|
||||
|
||||
- name: Sweep Cargo target cache
|
||||
shell: bash
|
||||
run: |
|
||||
cargo sweep --maxsize 10GB
|
||||
cargo sweep --time 30
|
||||
|
||||
|
||||
package-npx-cli:
|
||||
needs: [bump-version, build-frontend, build-backend]
|
||||
runs-on: ubuntu-latest-m
|
||||
strategy:
|
||||
# NOTE: This matrix must be kept in sync with build-backend job above
|
||||
# GitHub Actions doesn't support YAML anchors, so duplication is unavoidable
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-unknown-linux-musl
|
||||
name: linux-x64
|
||||
binary: vibe-kanban
|
||||
mcp_binary: vibe-kanban-mcp
|
||||
review_binary: vibe-kanban-review
|
||||
- target: x86_64-pc-windows-msvc
|
||||
name: windows-x64
|
||||
binary: vibe-kanban.exe
|
||||
mcp_binary: vibe-kanban-mcp.exe
|
||||
review_binary: vibe-kanban-review.exe
|
||||
- target: x86_64-apple-darwin
|
||||
name: macos-x64
|
||||
binary: vibe-kanban
|
||||
mcp_binary: vibe-kanban-mcp
|
||||
review_binary: vibe-kanban-review
|
||||
- target: aarch64-apple-darwin
|
||||
name: macos-arm64
|
||||
binary: vibe-kanban
|
||||
mcp_binary: vibe-kanban-mcp
|
||||
review_binary: vibe-kanban-review
|
||||
- target: aarch64-pc-windows-msvc
|
||||
name: windows-arm64
|
||||
binary: vibe-kanban.exe
|
||||
mcp_binary: vibe-kanban-mcp.exe
|
||||
review_binary: vibe-kanban-review.exe
|
||||
- target: aarch64-unknown-linux-musl
|
||||
name: linux-arm64
|
||||
binary: vibe-kanban
|
||||
mcp_binary: vibe-kanban-mcp
|
||||
review_binary: vibe-kanban-review
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.bump-version.outputs.new_tag }}
|
||||
|
||||
- name: Download frontend artifact
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: frontend-dist
|
||||
path: packages/local-web/dist/
|
||||
|
||||
- name: Download backend binary artifact
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: backend-binary-${{ matrix.name }}
|
||||
path: dist/
|
||||
|
||||
- name: List downloaded artifacts
|
||||
run: |
|
||||
echo "Downloaded backend binaries:"
|
||||
find dist/
|
||||
|
||||
- name: Create platform package
|
||||
if: matrix.name != 'macos-arm64' && matrix.name != 'macos-x64'
|
||||
run: |
|
||||
mkdir -p npx-cli/dist/${{ matrix.name }}
|
||||
mkdir vibe-kanban-${{ matrix.name }}
|
||||
mkdir vibe-kanban-mcp-${{ matrix.name }}
|
||||
mkdir vibe-kanban-review-${{ matrix.name }}
|
||||
|
||||
cp dist/vibe-kanban-${{ matrix.name }}* vibe-kanban-${{ matrix.name }}/${{ matrix.binary }}
|
||||
cp dist/vibe-kanban-mcp-${{ matrix.name }}* vibe-kanban-mcp-${{ matrix.name }}/${{ matrix.mcp_binary }}
|
||||
cp dist/vibe-kanban-review-${{ matrix.name }}* vibe-kanban-review-${{ matrix.name }}/${{ matrix.review_binary }}
|
||||
|
||||
zip -j npx-cli/dist/${{ matrix.name }}/vibe-kanban.zip vibe-kanban-${{ matrix.name }}/${{ matrix.binary }}
|
||||
zip -j npx-cli/dist/${{ matrix.name }}/vibe-kanban-mcp.zip vibe-kanban-mcp-${{ matrix.name }}/${{ matrix.mcp_binary }}
|
||||
zip -j npx-cli/dist/${{ matrix.name }}/vibe-kanban-review.zip vibe-kanban-review-${{ matrix.name }}/${{ matrix.review_binary }}
|
||||
|
||||
- name: Create platform package (macOS)
|
||||
if: matrix.name == 'macos-arm64' || matrix.name == 'macos-x64'
|
||||
run: |
|
||||
mkdir -p npx-cli/dist/${{ matrix.name }}
|
||||
mkdir vibe-kanban-${{ matrix.name }}
|
||||
cp dist/vibe-kanban-${{ matrix.name }}* npx-cli/dist/${{ matrix.name }}/vibe-kanban.zip
|
||||
cp dist/vibe-kanban-mcp-${{ matrix.name }}* npx-cli/dist/${{ matrix.name }}/vibe-kanban-mcp.zip
|
||||
cp dist/vibe-kanban-review-${{ matrix.name }}* npx-cli/dist/${{ matrix.name }}/vibe-kanban-review.zip
|
||||
|
||||
- name: Upload platform package artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: npx-platform-${{ matrix.name }}
|
||||
path: npx-cli/dist/
|
||||
retention-days: 1
|
||||
|
||||
upload-to-r2:
|
||||
needs: [bump-version, package-npx-cli]
|
||||
runs-on: ubuntu-latest-m
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.bump-version.outputs.new_tag }}
|
||||
|
||||
- name: Download all platform packages
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: npx-platform-*
|
||||
path: binaries/
|
||||
merge-multiple: true
|
||||
|
||||
- name: List downloaded binaries
|
||||
run: |
|
||||
echo "Downloaded binaries:"
|
||||
find binaries/
|
||||
|
||||
- name: Configure AWS CLI for R2
|
||||
run: |
|
||||
aws configure set aws_access_key_id ${{ secrets.R2_BINARIES_ACCESS_KEY_ID }}
|
||||
aws configure set aws_secret_access_key ${{ secrets.R2_BINARIES_SECRET_ACCESS_KEY }}
|
||||
aws configure set default.region auto
|
||||
|
||||
- name: Generate manifest and upload to R2
|
||||
run: |
|
||||
TAG="${{ needs.bump-version.outputs.new_tag }}"
|
||||
ENDPOINT="${{ secrets.R2_BINARIES_ENDPOINT }}"
|
||||
BUCKET="${{ secrets.R2_BINARIES_BUCKET }}"
|
||||
|
||||
# Generate version manifest with checksums
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const crypto = require('crypto');
|
||||
const manifest = { version: '$TAG', platforms: {} };
|
||||
const platforms = ['linux-x64', 'linux-arm64', 'windows-x64', 'windows-arm64', 'macos-x64', 'macos-arm64'];
|
||||
const binaries = ['vibe-kanban', 'vibe-kanban-mcp', 'vibe-kanban-review'];
|
||||
|
||||
for (const platform of platforms) {
|
||||
manifest.platforms[platform] = {};
|
||||
for (const binary of binaries) {
|
||||
const zipPath = \`binaries/\${platform}/\${binary}.zip\`;
|
||||
if (fs.existsSync(zipPath)) {
|
||||
const data = fs.readFileSync(zipPath);
|
||||
manifest.platforms[platform][binary] = {
|
||||
sha256: crypto.createHash('sha256').update(data).digest('hex'),
|
||||
size: data.length
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
fs.writeFileSync('version-manifest.json', JSON.stringify(manifest, null, 2));
|
||||
console.log('Generated manifest:');
|
||||
console.log(JSON.stringify(manifest, null, 2));
|
||||
"
|
||||
|
||||
# Upload binaries (use full tag for path, allows multiple pre-releases to coexist)
|
||||
for platform in linux-x64 linux-arm64 windows-x64 windows-arm64 macos-x64 macos-arm64; do
|
||||
for binary in vibe-kanban vibe-kanban-mcp vibe-kanban-review; do
|
||||
if [ -f "binaries/$platform/$binary.zip" ]; then
|
||||
echo "Uploading binaries/$platform/$binary.zip..."
|
||||
aws s3 cp "binaries/$platform/$binary.zip" \
|
||||
"s3://$BUCKET/binaries/$TAG/$platform/$binary.zip" \
|
||||
--endpoint-url "$ENDPOINT"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
# Upload version manifest
|
||||
echo "Uploading version manifest..."
|
||||
aws s3 cp version-manifest.json \
|
||||
"s3://$BUCKET/binaries/$TAG/manifest.json" \
|
||||
--endpoint-url "$ENDPOINT" --content-type "application/json"
|
||||
|
||||
# Update global manifest
|
||||
VERSION="${{ needs.bump-version.outputs.new_version }}"
|
||||
echo "Updating global manifest..."
|
||||
echo "{\"latest\": \"$VERSION\"}" | aws s3 cp - \
|
||||
"s3://$BUCKET/binaries/manifest.json" \
|
||||
--endpoint-url "$ENDPOINT" --content-type "application/json"
|
||||
|
||||
- name: Verify upload
|
||||
run: |
|
||||
TAG="${{ needs.bump-version.outputs.new_tag }}"
|
||||
ENDPOINT="${{ secrets.R2_BINARIES_ENDPOINT }}"
|
||||
BUCKET="${{ secrets.R2_BINARIES_BUCKET }}"
|
||||
|
||||
echo "Listing uploaded files..."
|
||||
aws s3 ls "s3://$BUCKET/binaries/$TAG/" \
|
||||
--endpoint-url "$ENDPOINT" \
|
||||
--recursive
|
||||
|
||||
build-tauri:
|
||||
needs: [bump-version, build-frontend]
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: aarch64-apple-darwin
|
||||
os: macos-15-xlarge
|
||||
platform: darwin-aarch64
|
||||
- target: x86_64-apple-darwin
|
||||
os: macos-15-xlarge
|
||||
platform: darwin-x86_64
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
os: ubuntu-latest-m
|
||||
platform: linux-x86_64
|
||||
- target: x86_64-pc-windows-msvc
|
||||
os: windows-latest
|
||||
platform: windows-x86_64
|
||||
env:
|
||||
CARGO_INCREMENTAL: "0"
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
SCCACHE_CACHE_SIZE: "10G"
|
||||
CARGO_HOME: ${{ github.workspace }}/.cargo
|
||||
RUSTUP_HOME: ${{ github.workspace }}/.rustup
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.bump-version.outputs.new_tag }}
|
||||
|
||||
- name: Setup sccache
|
||||
uses: BloopAI/sccache-action@main
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Install Linux dependencies
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libwebkit2gtk-4.1-dev build-essential \
|
||||
libssl-dev libayatana-appindicator3-dev librsvg2-dev \
|
||||
libxdo-dev file pkg-config
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Install Tauri CLI
|
||||
run: cargo install tauri-cli --version "^2" --locked
|
||||
|
||||
- name: Download frontend artifact
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: frontend-dist
|
||||
path: frontend/dist/
|
||||
|
||||
- name: Patch tauri.conf.json for CI
|
||||
run: |
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const conf = JSON.parse(fs.readFileSync('crates/tauri-app/tauri.conf.json', 'utf8'));
|
||||
// Inject the real updater endpoint (replaces __TAURI_UPDATE_ENDPOINT__ placeholder)
|
||||
const endpoint = '${{ secrets.R2_BINARIES_PUBLIC_URL }}/binaries/tauri-update/latest.json';
|
||||
conf.plugins.updater.endpoints = conf.plugins.updater.endpoints.map(e =>
|
||||
e === '__TAURI_UPDATE_ENDPOINT__' ? endpoint : e
|
||||
);
|
||||
// Remove beforeBuildCommand — frontend is already pre-built and downloaded as an artifact
|
||||
delete conf.build.beforeBuildCommand;
|
||||
fs.writeFileSync('crates/tauri-app/tauri.conf.json', JSON.stringify(conf, null, 2) + '\n');
|
||||
"
|
||||
|
||||
- name: Set up Apple notarization key
|
||||
if: runner.os == 'macOS'
|
||||
env:
|
||||
API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
|
||||
API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
|
||||
API_PRIVATE_KEY: ${{ secrets.APPLE_API_PRIVATE_KEY }}
|
||||
run: |
|
||||
# Write the .p8 key file where Tauri/notarytool can find it
|
||||
mkdir -p ~/.private_keys
|
||||
KEY_PATH="$HOME/.private_keys/AuthKey_${API_KEY_ID}.p8"
|
||||
printf '%s' "$API_PRIVATE_KEY" > "$KEY_PATH"
|
||||
|
||||
echo "APPLE_API_KEY=$API_KEY_ID" >> $GITHUB_ENV
|
||||
echo "APPLE_API_ISSUER=$API_ISSUER" >> $GITHUB_ENV
|
||||
echo "APPLE_API_KEY_PATH=$KEY_PATH" >> $GITHUB_ENV
|
||||
|
||||
- name: Build Tauri app
|
||||
run: cargo tauri build --target ${{ matrix.target }} --ci
|
||||
env:
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE_P12_BASE64 }}
|
||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||
APPLE_API_KEY: ${{ env.APPLE_API_KEY }}
|
||||
APPLE_API_ISSUER: ${{ env.APPLE_API_ISSUER }}
|
||||
APPLE_API_KEY_PATH: ${{ env.APPLE_API_KEY_PATH }}
|
||||
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
|
||||
POSTHOG_API_ENDPOINT: ${{ secrets.POSTHOG_API_ENDPOINT }}
|
||||
VK_SHARED_API_BASE: ${{ secrets.VK_SHARED_API_BASE }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
|
||||
- name: Collect updater artifacts and installers
|
||||
run: |
|
||||
mkdir -p tauri-artifacts/${{ matrix.platform }}
|
||||
# Collect updater artifacts (.sig files and their corresponding bundles)
|
||||
find target/${{ matrix.target }}/release/bundle -name "*.sig" | while read sig; do
|
||||
artifact="${sig%.sig}"
|
||||
if [ -f "$artifact" ]; then
|
||||
cp "$artifact" "tauri-artifacts/${{ matrix.platform }}/"
|
||||
cp "$sig" "tauri-artifacts/${{ matrix.platform }}/"
|
||||
echo "Collected updater artifact: $(basename $artifact)"
|
||||
fi
|
||||
done
|
||||
# Collect installer files for GitHub Release (DMG, AppImage, deb, msi, NSIS exe)
|
||||
find target/${{ matrix.target }}/release/bundle \
|
||||
\( -name "*.dmg" -o -name "*.AppImage" -o -name "*.deb" -o -name "*.msi" -o -name "*-setup.exe" \) | while read f; do
|
||||
cp "$f" "tauri-artifacts/${{ matrix.platform }}/"
|
||||
echo "Collected installer: $(basename $f)"
|
||||
done
|
||||
echo "All artifacts for ${{ matrix.platform }}:"
|
||||
ls -la tauri-artifacts/${{ matrix.platform }}/
|
||||
|
||||
- name: Clean up signing keys
|
||||
if: always() && runner.os == 'macOS'
|
||||
run: rm -rf ~/.private_keys
|
||||
|
||||
- name: Upload Tauri artifacts
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: tauri-artifacts-${{ matrix.platform }}
|
||||
path: tauri-artifacts/
|
||||
retention-days: 1
|
||||
|
||||
upload-tauri-update:
|
||||
needs: [bump-version, build-tauri]
|
||||
runs-on: ubuntu-latest-m
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.bump-version.outputs.new_tag }}
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Download all Tauri artifacts
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: tauri-artifacts-*
|
||||
path: tauri-artifacts/
|
||||
merge-multiple: true
|
||||
|
||||
- name: List Tauri artifacts
|
||||
run: find tauri-artifacts/
|
||||
|
||||
- name: Generate updater manifest
|
||||
run: |
|
||||
node scripts/generate-tauri-update-json.js \
|
||||
--version "${{ needs.bump-version.outputs.new_version }}" \
|
||||
--notes "Release ${{ needs.bump-version.outputs.new_tag }}" \
|
||||
--artifacts-dir ./tauri-artifacts \
|
||||
--download-base "${{ secrets.R2_BINARIES_PUBLIC_URL }}/binaries/${{ needs.bump-version.outputs.new_tag }}/tauri" \
|
||||
--output latest.json
|
||||
echo "Generated latest.json:"
|
||||
cat latest.json
|
||||
|
||||
- name: Configure AWS CLI for R2
|
||||
run: |
|
||||
aws configure set aws_access_key_id ${{ secrets.R2_BINARIES_ACCESS_KEY_ID }}
|
||||
aws configure set aws_secret_access_key ${{ secrets.R2_BINARIES_SECRET_ACCESS_KEY }}
|
||||
aws configure set default.region auto
|
||||
|
||||
- name: Upload Tauri artifacts and update manifest to R2
|
||||
run: |
|
||||
TAG="${{ needs.bump-version.outputs.new_tag }}"
|
||||
ENDPOINT="${{ secrets.R2_BINARIES_ENDPOINT }}"
|
||||
BUCKET="${{ secrets.R2_BINARIES_BUCKET }}"
|
||||
|
||||
# Upload individual platform artifacts
|
||||
for platform in darwin-aarch64 darwin-x86_64 linux-x86_64 windows-x86_64; do
|
||||
if [ -d "tauri-artifacts/$platform" ]; then
|
||||
for file in tauri-artifacts/$platform/*; do
|
||||
[ -f "$file" ] || continue
|
||||
# Skip .sig files from artifact upload (signatures are in latest.json)
|
||||
[[ "$file" == *.sig ]] && continue
|
||||
filename=$(basename "$file")
|
||||
echo "Uploading $filename for $platform..."
|
||||
aws s3 cp "$file" \
|
||||
"s3://$BUCKET/binaries/$TAG/tauri/$filename" \
|
||||
--endpoint-url "$ENDPOINT"
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# Upload latest.json to the fixed update endpoint path
|
||||
echo "Uploading updater manifest..."
|
||||
aws s3 cp latest.json \
|
||||
"s3://$BUCKET/binaries/tauri-update/latest.json" \
|
||||
--endpoint-url "$ENDPOINT" --content-type "application/json"
|
||||
|
||||
echo "Update manifest uploaded to: binaries/tauri-update/latest.json"
|
||||
|
||||
create-prerelease:
|
||||
needs: [bump-version, build-frontend, upload-to-r2, upload-tauri-update]
|
||||
runs-on: ubuntu-latest-m
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.bump-version.outputs.new_tag }}
|
||||
|
||||
- name: Download frontend artifact
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
name: frontend-dist
|
||||
path: packages/local-web/dist/
|
||||
|
||||
- name: Download Tauri artifacts for release
|
||||
uses: actions/download-artifact@v7
|
||||
with:
|
||||
pattern: tauri-artifacts-*
|
||||
path: tauri-release/
|
||||
merge-multiple: true
|
||||
|
||||
- name: Collect Tauri installers for release
|
||||
run: |
|
||||
mkdir -p tauri-installers
|
||||
find tauri-release \( -name "*.dmg" -o -name "*.AppImage" -o -name "*.deb" -o -name "*.msi" -o -name "*-setup.exe" \) \
|
||||
-exec cp {} tauri-installers/ \;
|
||||
echo "Tauri installers for release:"
|
||||
ls -la tauri-installers/ 2>/dev/null || echo "No installers found"
|
||||
|
||||
- name: List downloaded artifacts
|
||||
run: |
|
||||
echo "Web dist:"
|
||||
find packages/local-web/dist
|
||||
|
||||
- name: Zip frontend
|
||||
run: |
|
||||
mkdir vibe-kanban-${{ needs.bump-version.outputs.new_tag }}
|
||||
mv packages/local-web/dist vibe-kanban-${{ needs.bump-version.outputs.new_tag }}
|
||||
zip -r vibe-kanban-${{ needs.bump-version.outputs.new_tag }}.zip vibe-kanban-${{ needs.bump-version.outputs.new_tag }}
|
||||
|
||||
- name: Setup Node for npm pack
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Inject R2 URL and tag, then Pack
|
||||
run: |
|
||||
cd npx-cli
|
||||
# Replace placeholders with actual values
|
||||
sed -i "s|__R2_PUBLIC_URL__|${{ secrets.R2_BINARIES_PUBLIC_URL }}|g" bin/download.js
|
||||
sed -i "s|__BINARY_TAG__|${{ needs.bump-version.outputs.new_tag }}|g" bin/download.js
|
||||
npm pack
|
||||
|
||||
- name: Create GitHub Pre-Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ needs.bump-version.outputs.new_tag }}
|
||||
name: Pre-release ${{ needs.bump-version.outputs.new_tag }}
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
files: |
|
||||
vibe-kanban-${{ needs.bump-version.outputs.new_tag }}.zip
|
||||
npx-cli/vibe-kanban-*.tgz
|
||||
tauri-installers/*
|
||||
143
.github/workflows/publish.yml
vendored
Normal file
143
.github/workflows/publish.yml
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
name: Publish to npm
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag_name:
|
||||
description: "Release tag (e.g., v1.2.3)"
|
||||
required: true
|
||||
release_id:
|
||||
description: "GitHub release ID"
|
||||
required: true
|
||||
|
||||
concurrency:
|
||||
group: publish
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
id-token: write # Required for OIDC trusted publishing
|
||||
|
||||
env:
|
||||
NODE_VERSION: 22
|
||||
PNPM_VERSION: 10.13.1
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
# Only run for main app releases (not remote-v* tags) that were converted from pre-release
|
||||
if: github.event.release.prerelease == false && !startsWith(github.event.release.tag_name, 'remote-')
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.release.tag_name || inputs.tag_name }}
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Upgrade npm for OIDC support
|
||||
run: npm install -g npm@latest
|
||||
|
||||
- name: Download release assets
|
||||
uses: actions/github-script@v8
|
||||
env:
|
||||
RELEASE_ID: ${{ inputs.release_id }}
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const releaseId = context.payload.release?.id || process.env.RELEASE_ID;
|
||||
console.log("releaseId:", releaseId);
|
||||
|
||||
if (!releaseId) {
|
||||
core.setFailed('No release ID found.');
|
||||
return;
|
||||
}
|
||||
|
||||
const release = await github.rest.repos.getRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: releaseId
|
||||
});
|
||||
|
||||
// Find the .tgz file
|
||||
const tgzAsset = release.data.assets.find(asset => asset.name.endsWith('.tgz'));
|
||||
|
||||
if (!tgzAsset) {
|
||||
core.setFailed('No .tgz file found in release assets');
|
||||
return;
|
||||
}
|
||||
|
||||
// Download the asset
|
||||
const response = await github.rest.repos.getReleaseAsset({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
asset_id: tgzAsset.id,
|
||||
headers: {
|
||||
Accept: 'application/octet-stream'
|
||||
}
|
||||
});
|
||||
|
||||
// Save to npx-cli directory
|
||||
const filePath = path.join('npx-cli', tgzAsset.name);
|
||||
fs.writeFileSync(filePath, Buffer.from(response.data));
|
||||
|
||||
console.log(`Downloaded ${tgzAsset.name} to ${filePath}`);
|
||||
|
||||
// Set output for next step
|
||||
core.setOutput('package-file', filePath);
|
||||
core.setOutput('package-name', tgzAsset.name);
|
||||
|
||||
- name: Verify package integrity
|
||||
id: verify
|
||||
run: |
|
||||
cd npx-cli
|
||||
|
||||
# List files to confirm download
|
||||
ls -la *.tgz
|
||||
|
||||
# Verify the package can be read
|
||||
npm pack --dry-run || echo "Note: This is expected to show differences since we're using the pre-built package"
|
||||
|
||||
# Extract package name from the downloaded file
|
||||
PACKAGE_FILE=$(ls *.tgz | head -n1)
|
||||
echo "package-file=$PACKAGE_FILE" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Publish to npm
|
||||
run: |
|
||||
cd npx-cli
|
||||
|
||||
# Publish the exact same package that was tested
|
||||
PACKAGE_FILE="${{ steps.verify.outputs.package-file }}"
|
||||
|
||||
echo "Publishing $PACKAGE_FILE to npm..."
|
||||
npm publish "$PACKAGE_FILE" --provenance --access public
|
||||
|
||||
echo "✅ Successfully published to npm!"
|
||||
|
||||
- name: Update release description
|
||||
uses: actions/github-script@v8
|
||||
env:
|
||||
RELEASE_ID: ${{ inputs.release_id }}
|
||||
with:
|
||||
script: |
|
||||
const releaseId = context.payload.release?.id || process.env.RELEASE_ID;;
|
||||
|
||||
// Fetch the release to get the current body
|
||||
const release = await github.rest.repos.getRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: releaseId
|
||||
});
|
||||
|
||||
const currentBody = release.data.body || '';
|
||||
await github.rest.repos.updateRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
release_id: releaseId,
|
||||
body: currentBody + '\n\n✅ **Published to npm registry**'
|
||||
});
|
||||
28
.github/workflows/relay-deploy-dev.yml
vendored
Normal file
28
.github/workflows/relay-deploy-dev.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Relay Deploy Dev
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- crates/relay-tunnel/**
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
run-relay-deploy:
|
||||
name: Deploy Relay Dev
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Dispatch dev relay deployment workflow
|
||||
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
|
||||
with:
|
||||
token: ${{ secrets.REMOTE_DEPLOYMENT_TOKEN }}
|
||||
repository: BloopAI/vibe-kanban-remote-deployment
|
||||
event-type: vibe-kanban-relay-deploy-dev
|
||||
client-payload: |
|
||||
{
|
||||
"ref": "${{ github.ref_name }}",
|
||||
"sha": "${{ github.sha }}"
|
||||
}
|
||||
110
.github/workflows/relay-deploy-prod.yml
vendored
Normal file
110
.github/workflows/relay-deploy-prod.yml
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
name: Deploy Relay Prod
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_type:
|
||||
description: "Version bump type"
|
||||
required: true
|
||||
default: "patch"
|
||||
type: choice
|
||||
options:
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
|
||||
concurrency:
|
||||
group: relay-deploy-${{ github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
RUST_TOOLCHAIN: nightly-2025-12-04
|
||||
|
||||
jobs:
|
||||
release-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cache cargo-edit
|
||||
uses: actions/cache@v5
|
||||
id: cache-cargo-edit
|
||||
with:
|
||||
path: ~/.cargo/bin/cargo-set-version
|
||||
key: cargo-edit-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}
|
||||
|
||||
- name: Install cargo-edit
|
||||
if: steps.cache-cargo-edit.outputs.cache-hit != 'true'
|
||||
run: cargo install cargo-edit
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
||||
|
||||
- name: Determine and update version
|
||||
id: version
|
||||
run: |
|
||||
# Get current version from crates/relay-tunnel/Cargo.toml
|
||||
current_version=$(grep '^version = ' crates/relay-tunnel/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
|
||||
echo "Current relay-tunnel version: $current_version"
|
||||
|
||||
# Parse version components
|
||||
IFS='.' read -r major minor patch <<< "$current_version"
|
||||
|
||||
# Bump based on type
|
||||
case "${{ github.event.inputs.version_type }}" in
|
||||
major)
|
||||
major=$((major + 1))
|
||||
minor=0
|
||||
patch=0
|
||||
;;
|
||||
minor)
|
||||
minor=$((minor + 1))
|
||||
patch=0
|
||||
;;
|
||||
patch)
|
||||
patch=$((patch + 1))
|
||||
;;
|
||||
esac
|
||||
|
||||
new_version="${major}.${minor}.${patch}"
|
||||
new_tag="relay-v${new_version}"
|
||||
|
||||
# Update version in crates/relay-tunnel/Cargo.toml
|
||||
cd crates/relay-tunnel
|
||||
cargo set-version "$new_version"
|
||||
cd ../..
|
||||
|
||||
# Update workspace Cargo.lock
|
||||
cargo update relay-tunnel
|
||||
|
||||
echo "New version: $new_version"
|
||||
echo "New tag: $new_tag"
|
||||
echo "new_version=$new_version" >> $GITHUB_OUTPUT
|
||||
echo "new_tag=$new_tag" >> $GITHUB_OUTPUT
|
||||
echo "new_ref=$new_tag" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Commit changes and create tag
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add crates/relay-tunnel/Cargo.toml Cargo.lock
|
||||
git commit -m "chore: bump relay-tunnel version to ${{ steps.version.outputs.new_version }}"
|
||||
git tag -a ${{ steps.version.outputs.new_tag }} -m "Relay release ${{ steps.version.outputs.new_tag }}"
|
||||
git push
|
||||
git push --tags
|
||||
|
||||
- name: Dispatch relay deployment workflow
|
||||
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
|
||||
with:
|
||||
token: ${{ secrets.REMOTE_DEPLOYMENT_TOKEN }}
|
||||
repository: BloopAI/vibe-kanban-remote-deployment
|
||||
event-type: vibe-kanban-relay-deploy-prod
|
||||
client-payload: |
|
||||
{
|
||||
"ref": "${{ steps.version.outputs.new_ref }}",
|
||||
"sha": "${{ github.sha }}",
|
||||
"version": "${{ steps.version.outputs.new_version }}"
|
||||
}
|
||||
22
.github/workflows/relay-release.yml
vendored
Normal file
22
.github/workflows/relay-release.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Create Relay Release
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [relay-deploy-success]
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ github.event.client_payload.tag }}
|
||||
name: ${{ github.event.client_payload.tag }}
|
||||
generate_release_notes: true
|
||||
body: |
|
||||
## Relay Tunnel Service Release
|
||||
|
||||
Deployed to ${{ github.event.client_payload.environment }}
|
||||
29
.github/workflows/remote-deploy-dev.yml
vendored
Normal file
29
.github/workflows/remote-deploy-dev.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Remote Deploy Dev
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- crates/remote/**
|
||||
- packages/remote-web/**
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
run-remote-deploy:
|
||||
name: Deploy Remote Dev
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Dispatch dev remote deployment workflow
|
||||
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
|
||||
with:
|
||||
token: ${{ secrets.REMOTE_DEPLOYMENT_TOKEN }}
|
||||
repository: BloopAI/vibe-kanban-remote-deployment
|
||||
event-type: vibe-kanban-remote-deploy-dev
|
||||
client-payload: |
|
||||
{
|
||||
"ref": "${{ github.ref_name }}",
|
||||
"sha": "${{ github.sha }}"
|
||||
}
|
||||
116
.github/workflows/remote-deploy-prod.yml
vendored
Normal file
116
.github/workflows/remote-deploy-prod.yml
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
name: Deploy Remote Prod
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version_type:
|
||||
description: "Version bump type"
|
||||
required: true
|
||||
default: "patch"
|
||||
type: choice
|
||||
options:
|
||||
- patch
|
||||
- minor
|
||||
- major
|
||||
|
||||
concurrency:
|
||||
group: remote-deploy-${{ github.ref_name }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
RUST_TOOLCHAIN: nightly-2025-12-04
|
||||
|
||||
jobs:
|
||||
release-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cache cargo-edit
|
||||
uses: actions/cache@v5
|
||||
id: cache-cargo-edit
|
||||
with:
|
||||
path: ~/.cargo/bin/cargo-set-version
|
||||
key: cargo-edit-${{ runner.os }}-${{ env.RUST_TOOLCHAIN }}
|
||||
|
||||
- name: Install cargo-edit
|
||||
if: steps.cache-cargo-edit.outputs.cache-hit != 'true'
|
||||
run: cargo install cargo-edit
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
ssh-key: ${{ secrets.DEPLOY_KEY }}
|
||||
|
||||
- name: Setup SSH Agent for private dependencies
|
||||
uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.VK_PRIVATE_DEPLOY_KEY }}
|
||||
|
||||
- name: Determine and update version
|
||||
id: version
|
||||
run: |
|
||||
# Get current version from crates/remote/Cargo.toml
|
||||
current_version=$(grep '^version = ' crates/remote/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
|
||||
echo "Current remote version: $current_version"
|
||||
|
||||
# Parse version components
|
||||
IFS='.' read -r major minor patch <<< "$current_version"
|
||||
|
||||
# Bump based on type
|
||||
case "${{ github.event.inputs.version_type }}" in
|
||||
major)
|
||||
major=$((major + 1))
|
||||
minor=0
|
||||
patch=0
|
||||
;;
|
||||
minor)
|
||||
minor=$((minor + 1))
|
||||
patch=0
|
||||
;;
|
||||
patch)
|
||||
patch=$((patch + 1))
|
||||
;;
|
||||
esac
|
||||
|
||||
new_version="${major}.${minor}.${patch}"
|
||||
new_tag="remote-v${new_version}"
|
||||
|
||||
# Update version in crates/remote/Cargo.toml
|
||||
cd crates/remote
|
||||
cargo set-version "$new_version"
|
||||
cargo update remote
|
||||
cd ../..
|
||||
|
||||
echo "New version: $new_version"
|
||||
echo "New tag: $new_tag"
|
||||
echo "new_version=$new_version" >> $GITHUB_OUTPUT
|
||||
echo "new_tag=$new_tag" >> $GITHUB_OUTPUT
|
||||
echo "new_ref=$new_tag" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Stop SSH agent
|
||||
run: ssh-agent -k
|
||||
|
||||
- name: Commit changes and create tag
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git add crates/remote/Cargo.toml crates/remote/Cargo.lock
|
||||
git commit -m "chore: bump remote version to ${{ steps.version.outputs.new_version }}"
|
||||
git tag -a ${{ steps.version.outputs.new_tag }} -m "Remote release ${{ steps.version.outputs.new_tag }}"
|
||||
git push
|
||||
git push --tags
|
||||
|
||||
- name: Dispatch remote deployment workflow
|
||||
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
|
||||
with:
|
||||
token: ${{ secrets.REMOTE_DEPLOYMENT_TOKEN }}
|
||||
repository: BloopAI/vibe-kanban-remote-deployment
|
||||
event-type: vibe-kanban-remote-deploy-prod
|
||||
client-payload: |
|
||||
{
|
||||
"ref": "${{ steps.version.outputs.new_ref }}",
|
||||
"sha": "${{ github.sha }}",
|
||||
"version": "${{ steps.version.outputs.new_version }}"
|
||||
}
|
||||
22
.github/workflows/remote-release.yml
vendored
Normal file
22
.github/workflows/remote-release.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Create Remote Release
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [remote-deploy-success]
|
||||
|
||||
jobs:
|
||||
create-release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ github.event.client_payload.tag }}
|
||||
name: ${{ github.event.client_payload.tag }}
|
||||
generate_release_notes: true
|
||||
body: |
|
||||
## Remote Service Release
|
||||
|
||||
✅ Deployed to ${{ github.event.client_payload.environment }}
|
||||
232
.github/workflows/test.yml
vendored
Normal file
232
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- .github/workflows/**
|
||||
- '!.github/workflows/test.yml'
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
NODE_VERSION: 22
|
||||
PNPM_VERSION: 10.13.1
|
||||
RUST_TOOLCHAIN: nightly-2025-12-04
|
||||
RUNNER_LABEL: &runner_label blacksmith-16vcpu-ubuntu-2404
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
outputs:
|
||||
frontend: ${{ steps.filter.outputs.frontend }}
|
||||
backend: ${{ steps.filter.outputs.backend }}
|
||||
backend-remote: ${{ steps.filter.outputs['backend-remote'] }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dorny/paths-filter@0bc4621a3135347011ad047f9ecf449bf72ce2bd # v3.0.0
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
frontend:
|
||||
- 'packages/local-web/**'
|
||||
- 'packages/web-core/**'
|
||||
- 'packages/remote-web/**'
|
||||
- 'packages/ui/**'
|
||||
- 'shared/**'
|
||||
- 'scripts/check-i18n.sh'
|
||||
- 'scripts/check-legacy-frontend-paths.sh'
|
||||
- 'scripts/legacy-frontend-paths-allowlist.txt'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'pnpm-workspace.yaml'
|
||||
- 'package.json'
|
||||
- '.npmrc'
|
||||
- '.github/workflows/test.yml'
|
||||
- '.github/actions/**'
|
||||
backend:
|
||||
- 'crates/api-types/**'
|
||||
- 'crates/db/**'
|
||||
- 'crates/deployment/**'
|
||||
- 'crates/executors/**'
|
||||
- 'crates/git/**'
|
||||
- 'crates/local-deployment/**'
|
||||
- 'crates/review/**'
|
||||
- 'crates/server/**'
|
||||
- 'crates/services/**'
|
||||
- 'crates/utils/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'shared/**'
|
||||
- 'scripts/prepare-db.js'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'package.json'
|
||||
- 'rustfmt.toml'
|
||||
- 'rust-toolchain.toml'
|
||||
- '.cargo/**'
|
||||
- '.github/workflows/test.yml'
|
||||
- '.github/actions/**'
|
||||
backend-remote:
|
||||
- 'crates/remote/**'
|
||||
- 'crates/api-types/**'
|
||||
- 'crates/utils/**'
|
||||
- 'Cargo.toml'
|
||||
- 'Cargo.lock'
|
||||
- 'shared/**'
|
||||
- 'rust-toolchain.toml'
|
||||
- '.cargo/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
- 'package.json'
|
||||
- '.github/workflows/test.yml'
|
||||
- '.github/actions/**'
|
||||
|
||||
frontend-checks:
|
||||
needs: changes
|
||||
if: always() && (needs.changes.outputs.frontend == 'true' || needs.changes.result == 'skipped')
|
||||
runs-on: *runner_label
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Node
|
||||
uses: ./.github/actions/setup-node
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Run frontend checks
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
run: |
|
||||
npx concurrently \
|
||||
--kill-others-on-fail \
|
||||
--names "local:lint,local:fmt,local:build,remote:fmt,remote:build,ui:check,ui:lint,ui:fmt,core:check,core:fmt,i18n,legacy" \
|
||||
--timings \
|
||||
"cd packages/local-web && npm run lint" \
|
||||
"cd packages/local-web && npm run format:check" \
|
||||
"cd packages/local-web && npm run build" \
|
||||
"cd packages/remote-web && npm run format:check" \
|
||||
"cd packages/remote-web && npm run build" \
|
||||
"cd packages/ui && npm run check" \
|
||||
"cd packages/ui && npm run lint" \
|
||||
"cd packages/ui && npm run format:check" \
|
||||
"cd packages/web-core && npm run check" \
|
||||
"cd packages/web-core && npm run format:check" \
|
||||
"GITHUB_BASE_REF=${{ github.base_ref || 'main' }} ./scripts/check-i18n.sh" \
|
||||
"./scripts/check-legacy-frontend-paths.sh"
|
||||
|
||||
backend-schema-checks:
|
||||
needs: changes
|
||||
if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped')
|
||||
runs-on: *runner_label
|
||||
env:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Rust
|
||||
uses: ./.github/actions/cargo-checks-common-setup
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cache-key: backend-schema-checks-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }}
|
||||
setup-node: 'true'
|
||||
setup-sqlx-cli: 'true'
|
||||
|
||||
- name: Check generated types
|
||||
run: npm run generate-types:check
|
||||
|
||||
- name: Sqlx checks
|
||||
run: npm run prepare-db:check
|
||||
|
||||
backend-remote-checks:
|
||||
needs: changes
|
||||
if: >-
|
||||
always()
|
||||
&& (needs.changes.outputs['backend-remote'] == 'true' || needs.changes.result == 'skipped')
|
||||
&& (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
|
||||
runs-on: *runner_label
|
||||
env:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Rust
|
||||
uses: ./.github/actions/cargo-checks-common-setup
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cache-key: backend-remote-checks-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }}
|
||||
setup-node: 'true'
|
||||
setup-sqlx-cli: 'true'
|
||||
|
||||
- name: Setup SSH Agent for private dependencies
|
||||
uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.VK_PRIVATE_DEPLOY_KEY }}
|
||||
|
||||
- name: Check remote Cargo.lock is consistent
|
||||
run: |
|
||||
cargo metadata --locked --format-version 1 --manifest-path crates/remote/Cargo.toml > /dev/null
|
||||
|
||||
- name: Check generated types
|
||||
run: npm run remote:generate-types:check
|
||||
|
||||
- name: Sqlx checks
|
||||
run: npm run remote:prepare-db:check
|
||||
|
||||
backend-clippy:
|
||||
needs: changes
|
||||
if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped')
|
||||
runs-on: *runner_label
|
||||
env:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Rust
|
||||
uses: ./.github/actions/cargo-checks-common-setup
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
components: rustfmt, clippy
|
||||
cache-key: backend-clippy-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }}
|
||||
|
||||
- name: Run Clippy and fmt checks
|
||||
run: |
|
||||
set -x
|
||||
cargo fmt --all -- --check & pid_fmt=$!
|
||||
cargo clippy --workspace --all-targets --exclude vibe-kanban-tauri -- -D warnings
|
||||
wait $pid_fmt
|
||||
|
||||
backend-test:
|
||||
needs: changes
|
||||
if: always() && (needs.changes.outputs.backend == 'true' || needs.changes.result == 'skipped')
|
||||
runs-on: *runner_label
|
||||
env:
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Rust
|
||||
uses: ./.github/actions/cargo-checks-common-setup
|
||||
with:
|
||||
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
||||
cache-key: backend-test-${{ runner.os }}-${{ runner.arch }}-${{ env.RUNNER_LABEL }}
|
||||
|
||||
- name: Install cargo-nextest
|
||||
uses: taiki-e/install-action@nextest
|
||||
|
||||
- name: Run Cargo tests
|
||||
run: cargo nextest run --workspace --exclude vibe-kanban-tauri
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -67,10 +67,10 @@ coverage/
|
||||
|
||||
.env
|
||||
packages/**/dist
|
||||
frontend/dist
|
||||
|
||||
build-npm-package-codesign.sh
|
||||
|
||||
npx-cli/bin/
|
||||
npx-cli/dist
|
||||
npx-cli/vibe-kanban-*
|
||||
vibe-kanban-*.tgz
|
||||
@@ -89,9 +89,3 @@ vibe-kanban-cloud/
|
||||
|
||||
# Vite temp files
|
||||
*.timestamp-*.mjs
|
||||
|
||||
# Mobile testing (per-developer, do not commit)
|
||||
*.ts.net.crt
|
||||
*.ts.net.key
|
||||
Caddyfile
|
||||
Caddyfile.dev
|
||||
|
||||
@@ -30,17 +30,17 @@ Do not manually edit shared/remote-types.ts, instead edit crates/remote/src/bin/
|
||||
- Run dev (web app + backend with ports auto-assigned): `pnpm run dev`
|
||||
- Backend (watch): `pnpm run backend:dev:watch`
|
||||
- Web app (dev): `pnpm run local-web:dev`
|
||||
- Type checks: `pnpm run check` (frontend + all backend Rust workspaces) and `pnpm run backend:check` (all backend Rust workspaces, including `crates/remote`)
|
||||
- Type checks: `pnpm run check` (workspace) and `pnpm run backend:check` (Rust cargo check)
|
||||
- Rust tests: `cargo test --workspace`
|
||||
- Generate TS types from Rust: `pnpm run generate-types` (or `generate-types:check` in CI)
|
||||
- Prepare SQLx (offline): `pnpm run prepare-db`
|
||||
- Prepare SQLx (remote package, postgres): `pnpm run remote:prepare-db`
|
||||
- Local NPX build: `pnpm run build:npx` then `pnpm pack` in `npx-cli/`
|
||||
- Format code: `pnpm run format` (runs `cargo fmt` for all backend Rust workspaces + web-core/web Prettier)
|
||||
- Lint: `pnpm run lint` (runs web/ui ESLint + `cargo clippy` for all backend Rust workspaces)
|
||||
- Format code: `pnpm run format` (runs `cargo fmt` + web-core/web Prettier)
|
||||
- Lint: `pnpm run lint` (runs web/ui ESLint + `cargo clippy`)
|
||||
|
||||
## Before Completing a Task
|
||||
- Run `pnpm run format` to format all Rust workspaces and web code.
|
||||
- Run `pnpm run format` to format all Rust and web code.
|
||||
|
||||
## Coding Style & Naming Conventions
|
||||
- Rust: `rustfmt` enforced (`rustfmt.toml`); group imports by crate; snake_case modules, PascalCase types.
|
||||
@@ -55,4 +55,3 @@ Do not manually edit shared/remote-types.ts, instead edit crates/remote/src/bin/
|
||||
- Use `.env` for local overrides; never commit secrets. Key envs: `FRONTEND_PORT`, `BACKEND_PORT`, `HOST`
|
||||
- Dev ports and assets are managed by `scripts/setup-dev-environment.js`.
|
||||
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# Contributing & Change Control
|
||||
|
||||
## Change Control Policy
|
||||
|
||||
All changes to production code are governed by formal change control procedures. These procedures ensure that modifications are reviewed, approved, and deployed in a controlled manner.
|
||||
|
||||
## Code Review Requirements
|
||||
|
||||
A maintainer must review pull requests before they are merged into any production branch. No code changes shall be merged without explicit approval from a qualified reviewer.
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
1. Create a feature or fix branch from the base branch.
|
||||
2. Make changes and open a pull request.
|
||||
3. Obtain the required review and approval from a maintainer.
|
||||
4. All required CI checks must pass before merging.
|
||||
5. Merge only after approval has been granted and CI checks have passed.
|
||||
|
||||
## Separation of Duties
|
||||
|
||||
Development, testing, and deployment of changes shall not be performed by a single individual without approval and oversight. All significant changes require independent review to ensure correctness, security, and alignment with project standards.
|
||||
|
||||
## Coding Practices
|
||||
|
||||
Contributors are expected to follow the project's coding standards throughout the development cycle. These standards cover code quality, style consistency, and security.
|
||||
|
||||
### Style & Formatting
|
||||
|
||||
- **Rust**: Code must be formatted with `rustfmt` (config in `rustfmt.toml`). Use `snake_case` for modules and functions, `PascalCase` for types. Group imports by crate.
|
||||
- **TypeScript/React**: Code must pass ESLint and Prettier (2 spaces, single quotes, 80-column width). Use `PascalCase` for components, `camelCase` for variables and functions, and `kebab-case` for file names.
|
||||
- Run `pnpm run format` before submitting a pull request.
|
||||
- Run `pnpm run lint` to verify there are no linting errors.
|
||||
|
||||
### Code Quality
|
||||
|
||||
- Keep functions small and focused on a single responsibility.
|
||||
- Write clear, self-documenting code. Add comments only where the logic is not self-evident.
|
||||
- Do not introduce unnecessary abstractions or over-engineer solutions.
|
||||
- Do not manually edit generated files (e.g., `shared/types.ts`). Modify the source and regenerate.
|
||||
|
||||
### Testing
|
||||
|
||||
- **Rust**: Add unit tests alongside code using `#[cfg(test)]`. Run `cargo test --workspace` to verify.
|
||||
- **TypeScript**: Ensure `pnpm run check` and `pnpm run lint` pass. Include lightweight tests (e.g., Vitest) for new runtime logic.
|
||||
- All CI checks must pass before a pull request can be merged.
|
||||
|
||||
### Security
|
||||
|
||||
- Never commit secrets, credentials, or API keys. Use `.env` for local configuration.
|
||||
- Be mindful of common vulnerabilities (injection, XSS, insecure deserialization) when writing code that handles user input or external data.
|
||||
- Report security issues privately to the maintainers rather than opening a public issue.
|
||||
|
||||
### Commit Messages
|
||||
|
||||
- Use clear, descriptive commit messages that explain the _why_ behind a change.
|
||||
- Prefix with a conventional type where appropriate (e.g., `feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:`).
|
||||
- Keep the subject line under 72 characters. Use the body for additional context if needed.
|
||||
|
||||
## Scope
|
||||
|
||||
These procedures apply to all production branches in this repository.
|
||||
@@ -1,15 +0,0 @@
|
||||
localhost:3001, relay.localhost:3001, *.relay.localhost:3001 {
|
||||
tls internal
|
||||
|
||||
@relay host relay.localhost *.relay.localhost
|
||||
handle @relay {
|
||||
reverse_proxy 127.0.0.1:8082
|
||||
}
|
||||
|
||||
@app expression `{http.request.host} == "localhost:3001" || {http.request.host} == "localhost"`
|
||||
handle @app {
|
||||
reverse_proxy 127.0.0.1:3000
|
||||
}
|
||||
|
||||
respond "not found" 404
|
||||
}
|
||||
4586
Cargo.lock
generated
4586
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
30
Cargo.toml
30
Cargo.toml
@@ -2,47 +2,30 @@
|
||||
resolver = "3"
|
||||
members = [
|
||||
"crates/api-types",
|
||||
"crates/relay-client",
|
||||
"crates/server",
|
||||
"crates/relay-types",
|
||||
"crates/trusted-key-auth",
|
||||
"crates/mcp",
|
||||
"crates/db",
|
||||
"crates/executors",
|
||||
"crates/services",
|
||||
"crates/worktree-manager",
|
||||
"crates/workspace-manager",
|
||||
"crates/relay-control",
|
||||
"crates/relay-protocol",
|
||||
"crates/relay-ws",
|
||||
"crates/ws-bridge",
|
||||
"crates/relay-hosts",
|
||||
"crates/client-info",
|
||||
"crates/remote-info",
|
||||
"crates/utils",
|
||||
"crates/git",
|
||||
"crates/git-host",
|
||||
"crates/local-deployment",
|
||||
"crates/deployment",
|
||||
"crates/review",
|
||||
"crates/embedded-ssh",
|
||||
"crates/desktop-bridge",
|
||||
"crates/tauri-app",
|
||||
"crates/preview-proxy",
|
||||
"crates/relay-tunnel-core",
|
||||
"crates/relay-webrtc",
|
||||
]
|
||||
exclude = ["crates/remote", "crates/relay-tunnel"]
|
||||
exclude = ["crates/remote"]
|
||||
|
||||
[workspace.dependencies]
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
axum = { version = "0.8.4", features = ["macros", "multipart", "ws"] }
|
||||
tower-http = { version = "0.5", features = ["cors", "request-id", "trace", "fs", "validate-request", "compression-gzip", "compression-br"] }
|
||||
tower-http = { version = "0.5", features = ["cors", "request-id", "trace", "fs", "validate-request"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||
anyhow = "1.0"
|
||||
git2 = { version = "0.20.3", default-features = false }
|
||||
reqwest = { version = "0.13", default-features = false, features = ["json", "query", "stream", "rustls"] }
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls-webpki-roots-no-provider"] }
|
||||
rustls = { version = "0.23", default-features = false, features = ["aws_lc_rs", "std", "tls12"] }
|
||||
thiserror = "2.0.12"
|
||||
tracing = "0.1.43"
|
||||
@@ -51,10 +34,13 @@ ts-rs = { git = "https://github.com/xazukx/ts-rs.git", branch = "use-ts-enum", f
|
||||
schemars = { version = "1.0.4", features = ["derive", "chrono04", "uuid1", "preserve_order"] }
|
||||
serde_with = "3"
|
||||
async-trait = "0.1"
|
||||
aws-lc-sys = "=0.37.0"
|
||||
aws-lc-rs = "=1.16.0"
|
||||
|
||||
[profile.release]
|
||||
debug = 1
|
||||
split-debuginfo = "packed"
|
||||
strip = true
|
||||
|
||||
# Patches for codex-core's forked tokio-tungstenite with proxy support
|
||||
[patch.crates-io]
|
||||
tokio-tungstenite = { git = "https://github.com/openai-oss-forks/tokio-tungstenite", rev = "132f5b39c862e3a970f731d709608b3e6276d5f6" }
|
||||
tungstenite = { git = "https://github.com/openai-oss-forks/tungstenite-rs", rev = "9200079d3b54a1ff51072e24d81fd354f085156f" }
|
||||
|
||||
188
Dockerfile
188
Dockerfile
@@ -1,152 +1,82 @@
|
||||
# syntax=docker/dockerfile:1.6
|
||||
# Build stage
|
||||
FROM node:24-alpine AS builder
|
||||
|
||||
FROM node:24-alpine AS fe-builder
|
||||
# Install build dependencies
|
||||
RUN apk add --no-cache \
|
||||
curl \
|
||||
build-base \
|
||||
perl \
|
||||
llvm-dev \
|
||||
clang-dev
|
||||
|
||||
ARG POSTHOG_API_KEY=""
|
||||
ARG POSTHOG_API_ENDPOINT=""
|
||||
# Allow linking libclang on musl
|
||||
ENV RUSTFLAGS="-C target-feature=-crt-static"
|
||||
|
||||
# Install Rust
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
|
||||
ARG POSTHOG_API_KEY
|
||||
ARG POSTHOG_API_ENDPOINT
|
||||
|
||||
ENV VITE_PUBLIC_POSTHOG_KEY=$POSTHOG_API_KEY
|
||||
ENV VITE_PUBLIC_POSTHOG_HOST=$POSTHOG_API_ENDPOINT
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
ENV PNPM_HOME=/pnpm
|
||||
ENV PATH=${PNPM_HOME}:${PATH}
|
||||
ENV VITE_PUBLIC_POSTHOG_KEY=${POSTHOG_API_KEY}
|
||||
ENV VITE_PUBLIC_POSTHOG_HOST=${POSTHOG_API_ENDPOINT}
|
||||
ENV NODE_OPTIONS=--max-old-space-size=4096
|
||||
# Copy package files for dependency caching
|
||||
COPY package*.json pnpm-lock.yaml pnpm-workspace.yaml ./
|
||||
COPY packages/local-web/package*.json ./packages/local-web/
|
||||
COPY npx-cli/package*.json ./npx-cli/
|
||||
|
||||
RUN corepack enable
|
||||
RUN pnpm config set store-dir /pnpm/store
|
||||
# Install pnpm and dependencies
|
||||
RUN npm install -g pnpm && pnpm install
|
||||
|
||||
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
|
||||
COPY packages/local-web/package.json packages/local-web/package.json
|
||||
COPY packages/ui/package.json packages/ui/package.json
|
||||
COPY packages/web-core/package.json packages/web-core/package.json
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
|
||||
pnpm install --frozen-lockfile
|
||||
# Build application
|
||||
RUN npm run generate-types
|
||||
RUN cd packages/local-web && pnpm run build
|
||||
RUN cargo build --release --bin server
|
||||
|
||||
COPY packages/local-web/ packages/local-web/
|
||||
COPY packages/public/ packages/public/
|
||||
COPY packages/ui/ packages/ui/
|
||||
COPY packages/web-core/ packages/web-core/
|
||||
COPY shared/ shared/
|
||||
# Runtime stage
|
||||
FROM alpine:latest AS runtime
|
||||
|
||||
RUN pnpm -C packages/local-web build
|
||||
|
||||
FROM rust:1.93-slim-bookworm AS builder
|
||||
|
||||
ARG POSTHOG_API_KEY=""
|
||||
ARG POSTHOG_API_ENDPOINT=""
|
||||
ARG SENTRY_DSN=""
|
||||
ARG VK_SHARED_API_BASE=""
|
||||
|
||||
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
|
||||
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||
ENV CARGO_TARGET_DIR=/app/target
|
||||
ENV POSTHOG_API_KEY=${POSTHOG_API_KEY}
|
||||
ENV POSTHOG_API_ENDPOINT=${POSTHOG_API_ENDPOINT}
|
||||
ENV SENTRY_DSN=${SENTRY_DSN}
|
||||
ENV VK_SHARED_API_BASE=${VK_SHARED_API_BASE}
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
# Install runtime dependencies
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
git \
|
||||
libclang-dev \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY rust-toolchain.toml ./
|
||||
RUN cargo --version >/dev/null
|
||||
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY crates/api-types/Cargo.toml crates/api-types/Cargo.toml
|
||||
COPY crates/db/Cargo.toml crates/db/Cargo.toml
|
||||
COPY crates/deployment/Cargo.toml crates/deployment/Cargo.toml
|
||||
COPY crates/executors/Cargo.toml crates/executors/Cargo.toml
|
||||
COPY crates/git/Cargo.toml crates/git/Cargo.toml
|
||||
COPY crates/git-host/Cargo.toml crates/git-host/Cargo.toml
|
||||
COPY crates/local-deployment/Cargo.toml crates/local-deployment/Cargo.toml
|
||||
COPY crates/mcp/Cargo.toml crates/mcp/Cargo.toml
|
||||
COPY crates/relay-control/Cargo.toml crates/relay-control/Cargo.toml
|
||||
COPY crates/relay-hosts/Cargo.toml crates/relay-hosts/Cargo.toml
|
||||
COPY crates/relay-protocol/Cargo.toml crates/relay-protocol/Cargo.toml
|
||||
COPY crates/relay-tunnel-core/Cargo.toml crates/relay-tunnel-core/Cargo.toml
|
||||
COPY crates/relay-webrtc/Cargo.toml crates/relay-webrtc/Cargo.toml
|
||||
COPY crates/relay-ws/Cargo.toml crates/relay-ws/Cargo.toml
|
||||
COPY crates/review/Cargo.toml crates/review/Cargo.toml
|
||||
COPY crates/server/Cargo.toml crates/server/Cargo.toml
|
||||
COPY crates/server-info/Cargo.toml crates/server-info/Cargo.toml
|
||||
COPY crates/services/Cargo.toml crates/services/Cargo.toml
|
||||
COPY crates/tauri-app/Cargo.toml crates/tauri-app/Cargo.toml
|
||||
COPY crates/trusted-key-auth/Cargo.toml crates/trusted-key-auth/Cargo.toml
|
||||
COPY crates/utils/Cargo.toml crates/utils/Cargo.toml
|
||||
COPY crates/workspace-manager/Cargo.toml crates/workspace-manager/Cargo.toml
|
||||
COPY crates/worktree-manager/Cargo.toml crates/worktree-manager/Cargo.toml
|
||||
COPY crates/ws-bridge/Cargo.toml crates/ws-bridge/Cargo.toml
|
||||
|
||||
COPY crates/api-types/ crates/api-types/
|
||||
COPY crates/db/ crates/db/
|
||||
COPY crates/deployment/ crates/deployment/
|
||||
COPY crates/executors/ crates/executors/
|
||||
COPY crates/git/ crates/git/
|
||||
COPY crates/git-host/ crates/git-host/
|
||||
COPY crates/local-deployment/ crates/local-deployment/
|
||||
COPY crates/mcp/ crates/mcp/
|
||||
COPY crates/relay-control/ crates/relay-control/
|
||||
COPY crates/relay-hosts/ crates/relay-hosts/
|
||||
COPY crates/relay-protocol/ crates/relay-protocol/
|
||||
COPY crates/relay-tunnel-core/ crates/relay-tunnel-core/
|
||||
COPY crates/relay-webrtc/ crates/relay-webrtc/
|
||||
COPY crates/relay-ws/ crates/relay-ws/
|
||||
COPY crates/review/ crates/review/
|
||||
COPY crates/server/ crates/server/
|
||||
COPY crates/server-info/ crates/server-info/
|
||||
COPY crates/services/ crates/services/
|
||||
COPY crates/trusted-key-auth/ crates/trusted-key-auth/
|
||||
COPY crates/utils/ crates/utils/
|
||||
COPY crates/workspace-manager/ crates/workspace-manager/
|
||||
COPY crates/worktree-manager/ crates/worktree-manager/
|
||||
COPY crates/ws-bridge/ crates/ws-bridge/
|
||||
COPY assets/ assets/
|
||||
COPY --from=fe-builder /app/packages/local-web/dist packages/local-web/dist
|
||||
|
||||
RUN --mount=type=cache,id=cargo-registry,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,id=cargo-git,target=/usr/local/cargo/git \
|
||||
--mount=type=cache,id=workspace-target,target=/app/target \
|
||||
cargo build --locked --release --bin server \
|
||||
&& cp /app/target/release/server /usr/local/bin/server
|
||||
|
||||
FROM debian:bookworm-slim AS runtime
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
git \
|
||||
openssh-client \
|
||||
tini \
|
||||
wget \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& useradd --system --create-home --uid 10001 appuser
|
||||
libgcc \
|
||||
wget
|
||||
|
||||
WORKDIR /repos
|
||||
# Create app user for security
|
||||
RUN addgroup -g 1001 -S appgroup && \
|
||||
adduser -u 1001 -S appuser -G appgroup
|
||||
|
||||
COPY --from=builder /usr/local/bin/server /usr/local/bin/server
|
||||
# Copy binary from builder
|
||||
COPY --from=builder /app/target/release/server /usr/local/bin/server
|
||||
|
||||
RUN mkdir -p /repos \
|
||||
&& chown -R appuser:appuser /repos
|
||||
# Create repos directory and set permissions
|
||||
RUN mkdir -p /repos && \
|
||||
chown -R appuser:appgroup /repos
|
||||
|
||||
# Switch to non-root user
|
||||
USER appuser
|
||||
|
||||
# Set runtime environment
|
||||
ENV HOST=0.0.0.0
|
||||
ENV PORT=3000
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||||
CMD ["/bin/sh", "-c", "wget --spider -q http://127.0.0.1:${PORT:-3000}/health"]
|
||||
# Set working directory
|
||||
WORKDIR /repos
|
||||
|
||||
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/server"]
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --quiet --tries=1 --spider "http://${HOST:-localhost}:${PORT:-3000}" || exit 1
|
||||
|
||||
# Run the application
|
||||
ENTRYPOINT ["/sbin/tini", "--"]
|
||||
CMD ["server"]
|
||||
|
||||
46
README.md
46
README.md
@@ -1,9 +1,9 @@
|
||||
<p align="center">
|
||||
<a href="https://vibekanban.com">
|
||||
<picture>
|
||||
<source srcset="packages/public/vibe-kanban-logo-dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<source srcset="packages/public/vibe-kanban-logo.svg" media="(prefers-color-scheme: light)">
|
||||
<img src="packages/public/vibe-kanban-logo.svg" alt="Vibe Kanban Logo">
|
||||
<source srcset="packages/local-web/public/vibe-kanban-logo-dark.svg" media="(prefers-color-scheme: dark)">
|
||||
<source srcset="packages/local-web/public/vibe-kanban-logo.svg" media="(prefers-color-scheme: light)">
|
||||
<img src="packages/local-web/public/vibe-kanban-logo.svg" alt="Vibe Kanban Logo">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
@@ -19,33 +19,24 @@
|
||||
<a href="https://jobs.polymer.co/vibe-kanban?source=github"><strong>We're hiring!</strong></a>
|
||||
</h1>
|
||||
|
||||

|
||||

|
||||
|
||||
## Overview
|
||||
|
||||
In a world where software engineers spend most of their time planning and reviewing coding agents, the most impactful way to ship more is to get faster at planning and review.
|
||||
AI coding agents are increasingly writing the world's code and human engineers now spend the majority of their time planning, reviewing, and orchestrating tasks. Vibe Kanban streamlines this process, enabling you to:
|
||||
|
||||
Vibe Kanban is built for this. Use kanban issues to plan work, either privately or with your team. When you're ready to begin, create workspaces where coding agents can execute.
|
||||
|
||||
- **Plan with kanban issues** — create, prioritise, and assign issues on a kanban board
|
||||
- **Run coding agents in workspaces** — each workspace gives an agent a branch, a terminal, and a dev server
|
||||
- **Review diffs and leave inline comments** — send feedback directly to the agent without leaving the UI
|
||||
- **Preview your app** — built-in browser with devtools, inspect mode, and device emulation
|
||||
- **Switch between 10+ coding agents** — Claude Code, Codex, Gemini CLI, GitHub Copilot, Amp, Cursor, OpenCode, Droid, CCR, and Qwen Code
|
||||
- **Create pull requests and merge** — open PRs with AI-generated descriptions, review on GitHub, and merge
|
||||
|
||||

|
||||
|
||||
One command. Describe the work, review the diff, ship it.
|
||||
|
||||
```bash
|
||||
npx vibe-kanban
|
||||
```
|
||||
- Easily switch between different coding agents
|
||||
- Orchestrate the execution of multiple coding agents in parallel or in sequence
|
||||
- Quickly review work and start dev servers
|
||||
- Track the status of tasks that your coding agents are working on
|
||||
- Centralise configuration of coding agent MCP configs
|
||||
- Open projects remotely via SSH when running Vibe Kanban on a remote server
|
||||
|
||||
You can watch a video overview [here](https://youtu.be/TFT3KnZOOAk).
|
||||
|
||||
## Installation
|
||||
|
||||
Make sure you have authenticated with your favourite coding agent. A full list of supported coding agents can be found in the [docs](https://vibekanban.com/docs/supported-coding-agents). Then in your terminal run:
|
||||
Make sure you have authenticated with your favourite coding agent. A full list of supported coding agents can be found in the [docs](https://vibekanban.com/docs). Then in your terminal run:
|
||||
|
||||
```bash
|
||||
npx vibe-kanban
|
||||
@@ -53,12 +44,12 @@ npx vibe-kanban
|
||||
|
||||
## Documentation
|
||||
|
||||
Head to the [website](https://vibekanban.com/docs) for the latest documentation and user guides.
|
||||
Please head to the [website](https://vibekanban.com/docs) for the latest documentation and user guides.
|
||||
|
||||
## Self-Hosting
|
||||
|
||||
Want to host your own Vibe Kanban Cloud instance? See our [self-hosting guide](https://vibekanban.com/docs/self-hosting/deploy-docker).
|
||||
|
||||
Want to host your own Vibe Kanban Cloud instance? See our [self-hosting guide](https://vibekanban.com/docs/self-hosting).
|
||||
|
||||
## Support
|
||||
|
||||
We use [GitHub Discussions](https://github.com/BloopAI/vibe-kanban/discussions) for feature requests. Please open a discussion to create a feature request. For bugs please open an issue on this repo.
|
||||
@@ -124,9 +115,6 @@ The following environment variables can be configured at build time or runtime:
|
||||
| `MCP_PORT` | Runtime | Value of `BACKEND_PORT` | MCP server connection port |
|
||||
| `DISABLE_WORKTREE_CLEANUP` | Runtime | Not set | Disable all git worktree cleanup including orphan and expired workspace cleanup (for debugging) |
|
||||
| `VK_ALLOWED_ORIGINS` | Runtime | Not set | Comma-separated list of origins that are allowed to make backend API requests (e.g., `https://my-vibekanban-frontend.com`) |
|
||||
| `VK_SHARED_API_BASE` | Runtime | Not set | Base URL for the remote/cloud API used by the local desktop app |
|
||||
| `VK_SHARED_RELAY_API_BASE` | Runtime | Not set | Base URL for the relay API used by tunnel-mode connections |
|
||||
| `VK_TUNNEL` | Runtime | Not set | Enable relay tunnel mode when set (requires relay API base URL) |
|
||||
|
||||
**Build-time variables** must be set when running `pnpm run build`. **Runtime variables** are read when the application starts.
|
||||
|
||||
@@ -159,4 +147,4 @@ When running Vibe Kanban on a remote server (e.g., via systemctl, Docker, or clo
|
||||
|
||||
When configured, the "Open in VSCode" buttons will generate URLs like `vscode://vscode-remote/ssh-remote+user@host/path` that open your local editor and connect to the remote server.
|
||||
|
||||
See the [documentation](https://vibekanban.com/docs/settings/general) for detailed setup instructions.
|
||||
See the [documentation](https://vibekanban.com/docs/configuration-customisation/global-settings#remote-ssh-configuration) for detailed setup instructions.
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "api-types"
|
||||
version = "0.1.44"
|
||||
version = "0.1.19-pthis.2"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -5,6 +5,7 @@ use uuid::Uuid;
|
||||
|
||||
/// An attachment links a blob to an issue or comment.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[ts(export)]
|
||||
pub struct Attachment {
|
||||
pub id: Uuid,
|
||||
pub blob_id: Uuid,
|
||||
@@ -16,6 +17,7 @@ pub struct Attachment {
|
||||
|
||||
/// An attachment with its associated blob data (for API responses).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[ts(export)]
|
||||
pub struct AttachmentWithBlob {
|
||||
pub id: Uuid,
|
||||
pub blob_id: Uuid,
|
||||
@@ -50,6 +52,7 @@ pub struct ListAttachmentsResponse {
|
||||
|
||||
/// Response containing a presigned URL for an attachment file or thumbnail.
|
||||
#[derive(Debug, Serialize, Deserialize, TS)]
|
||||
#[ts(export)]
|
||||
pub struct AttachmentUrlResponse {
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use serde::Serialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, sqlx::FromRow, Serialize)]
|
||||
pub struct AuthSession {
|
||||
pub id: Uuid,
|
||||
pub user_id: Uuid,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub last_used_at: Option<DateTime<Utc>>,
|
||||
pub revoked_at: Option<DateTime<Utc>>,
|
||||
pub refresh_token_id: Option<Uuid>,
|
||||
pub refresh_token_issued_at: Option<DateTime<Utc>>,
|
||||
pub previous_refresh_token_id: Option<Uuid>,
|
||||
pub previous_refresh_token_grace_expires_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
impl AuthSession {
|
||||
pub fn last_activity_at(&self) -> DateTime<Utc> {
|
||||
self.last_used_at.unwrap_or(self.created_at)
|
||||
}
|
||||
|
||||
pub fn inactivity_duration(&self, now: DateTime<Utc>) -> Duration {
|
||||
now.signed_duration_since(self.last_activity_at())
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ use ts_rs::TS;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[ts(export)]
|
||||
pub struct Blob {
|
||||
pub id: Uuid,
|
||||
pub project_id: Uuid,
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct ExportRequest {
|
||||
pub organization_id: Uuid,
|
||||
/// If empty, exports all projects in the organization.
|
||||
pub project_ids: Vec<Uuid>,
|
||||
pub include_attachments: bool,
|
||||
}
|
||||
@@ -17,7 +17,7 @@ pub enum IssuePriority {
|
||||
Low,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS, sqlx::FromRow)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct Issue {
|
||||
pub id: Uuid,
|
||||
pub project_id: Uuid,
|
||||
@@ -39,23 +39,6 @@ pub struct Issue {
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum IssueSortField {
|
||||
SortOrder,
|
||||
Priority,
|
||||
CreatedAt,
|
||||
UpdatedAt,
|
||||
Title,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SortDirection {
|
||||
Asc,
|
||||
Desc,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct CreateIssueRequest {
|
||||
/// Optional client-generated ID. If not provided, server generates one.
|
||||
@@ -146,59 +129,12 @@ pub struct UpdateIssueRequest {
|
||||
pub extension_metadata: Option<Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ListIssuesQuery {
|
||||
pub project_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct SearchIssuesRequest {
|
||||
pub project_id: Uuid,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub status_id: Option<Uuid>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub status_ids: Option<Vec<Uuid>>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub priority: Option<IssuePriority>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub parent_issue_id: Option<Uuid>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub search: Option<String>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub simple_id: Option<String>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub assignee_user_id: Option<Uuid>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub tag_id: Option<Uuid>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub tag_ids: Option<Vec<Uuid>>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub sort_field: Option<IssueSortField>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub sort_direction: Option<SortDirection>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub limit: Option<i32>,
|
||||
#[ts(optional)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub offset: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct ListIssuesResponse {
|
||||
pub issues: Vec<Issue>,
|
||||
pub total_count: usize,
|
||||
pub limit: usize,
|
||||
pub offset: usize,
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::some_if_present;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct IssueAssignee {
|
||||
pub id: Uuid,
|
||||
@@ -21,6 +23,12 @@ pub struct CreateIssueAssigneeRequest {
|
||||
pub user_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, TS)]
|
||||
pub struct UpdateIssueAssigneeRequest {
|
||||
#[serde(default, deserialize_with = "some_if_present")]
|
||||
pub user_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ListIssueAssigneesQuery {
|
||||
pub issue_id: Uuid,
|
||||
|
||||
@@ -2,6 +2,8 @@ use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::some_if_present;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct IssueFollower {
|
||||
pub id: Uuid,
|
||||
@@ -19,6 +21,12 @@ pub struct CreateIssueFollowerRequest {
|
||||
pub user_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, TS)]
|
||||
pub struct UpdateIssueFollowerRequest {
|
||||
#[serde(default, deserialize_with = "some_if_present")]
|
||||
pub user_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ListIssueFollowersQuery {
|
||||
pub issue_id: Uuid,
|
||||
|
||||
@@ -5,6 +5,8 @@ use sqlx::Type;
|
||||
use ts_rs::TS;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::some_if_present;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Type, TS, JsonSchema)]
|
||||
#[sqlx(type_name = "issue_relationship_type", rename_all = "snake_case")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@@ -34,6 +36,14 @@ pub struct CreateIssueRelationshipRequest {
|
||||
pub relationship_type: IssueRelationshipType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, TS)]
|
||||
pub struct UpdateIssueRelationshipRequest {
|
||||
#[serde(default, deserialize_with = "some_if_present")]
|
||||
pub related_issue_id: Option<Uuid>,
|
||||
#[serde(default, deserialize_with = "some_if_present")]
|
||||
pub relationship_type: Option<IssueRelationshipType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ListIssueRelationshipsQuery {
|
||||
pub issue_id: Uuid,
|
||||
|
||||
@@ -2,6 +2,8 @@ use serde::{Deserialize, Serialize};
|
||||
use ts_rs::TS;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::some_if_present;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct IssueTag {
|
||||
pub id: Uuid,
|
||||
@@ -19,6 +21,12 @@ pub struct CreateIssueTagRequest {
|
||||
pub tag_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, TS)]
|
||||
pub struct UpdateIssueTagRequest {
|
||||
#[serde(default, deserialize_with = "some_if_present")]
|
||||
pub tag_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ListIssueTagsQuery {
|
||||
pub issue_id: Uuid,
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
pub mod attachment;
|
||||
pub mod auth;
|
||||
pub mod blob;
|
||||
pub mod export;
|
||||
pub mod issue;
|
||||
pub mod issue_assignee;
|
||||
pub mod issue_comment;
|
||||
@@ -18,6 +16,7 @@ pub mod issue_comment_reaction;
|
||||
pub mod issue_follower;
|
||||
pub mod issue_relationship;
|
||||
pub mod issue_tag;
|
||||
pub mod migration;
|
||||
pub mod notification;
|
||||
pub mod oauth;
|
||||
pub mod organization_member;
|
||||
@@ -33,9 +32,7 @@ pub mod workspace;
|
||||
pub mod workspaces;
|
||||
|
||||
pub use attachment::*;
|
||||
pub use auth::*;
|
||||
pub use blob::*;
|
||||
pub use export::*;
|
||||
pub use issue::*;
|
||||
pub use issue_assignee::*;
|
||||
pub use issue_comment::*;
|
||||
@@ -43,6 +40,7 @@ pub use issue_comment_reaction::*;
|
||||
pub use issue_follower::*;
|
||||
pub use issue_relationship::*;
|
||||
pub use issue_tag::*;
|
||||
pub use migration::*;
|
||||
pub use notification::*;
|
||||
pub use oauth::*;
|
||||
pub use organization_member::*;
|
||||
|
||||
50
crates/api-types/src/migration.rs
Normal file
50
crates/api-types/src/migration.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MigrateProjectRequest {
|
||||
pub organization_id: Uuid,
|
||||
pub name: String,
|
||||
pub color: String,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MigrateIssueRequest {
|
||||
pub project_id: Uuid,
|
||||
pub status_name: String,
|
||||
pub title: String,
|
||||
pub description: Option<String>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MigratePullRequestRequest {
|
||||
pub url: String,
|
||||
pub number: i32,
|
||||
pub status: String,
|
||||
pub merged_at: Option<DateTime<Utc>>,
|
||||
pub merge_commit_sha: Option<String>,
|
||||
pub target_branch_name: String,
|
||||
pub issue_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MigrateWorkspaceRequest {
|
||||
pub project_id: Uuid,
|
||||
pub issue_id: Option<Uuid>,
|
||||
pub local_workspace_id: Uuid,
|
||||
pub archived: bool,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BulkMigrateRequest<T> {
|
||||
pub items: Vec<T>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BulkMigrateResponse {
|
||||
pub ids: Vec<Uuid>,
|
||||
}
|
||||
@@ -1,34 +1,18 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use sqlx::Type;
|
||||
use ts_rs::TS;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{IssuePriority, some_if_present};
|
||||
use crate::some_if_present;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Type, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[sqlx(type_name = "notification_type", rename_all = "snake_case")]
|
||||
pub enum NotificationType {
|
||||
IssueCommentAdded,
|
||||
IssueStatusChanged,
|
||||
IssueAssigneeChanged,
|
||||
IssuePriorityChanged,
|
||||
IssueUnassigned,
|
||||
IssueCommentReaction,
|
||||
IssueDeleted,
|
||||
IssueTitleChanged,
|
||||
IssueDescriptionChanged,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum NotificationGroupKind {
|
||||
Single,
|
||||
IssueChanges,
|
||||
StatusChanges,
|
||||
Comments,
|
||||
Reactions,
|
||||
IssueDeleted,
|
||||
}
|
||||
|
||||
@@ -38,7 +22,7 @@ pub struct Notification {
|
||||
pub organization_id: Uuid,
|
||||
pub user_id: Uuid,
|
||||
pub notification_type: NotificationType,
|
||||
pub payload: NotificationPayload,
|
||||
pub payload: Value,
|
||||
pub issue_id: Option<Uuid>,
|
||||
pub comment_id: Option<Uuid>,
|
||||
pub seen: bool,
|
||||
@@ -46,38 +30,14 @@ pub struct Notification {
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize, TS)]
|
||||
pub struct NotificationPayload {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub deeplink_path: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub issue_id: Option<Uuid>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub issue_simple_id: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub issue_title: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub actor_user_id: Option<Uuid>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub comment_preview: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub old_status_id: Option<Uuid>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub new_status_id: Option<Uuid>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub old_status_name: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub new_status_name: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub new_title: Option<String>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub old_priority: Option<IssuePriority>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub new_priority: Option<IssuePriority>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub assignee_user_id: Option<Uuid>,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub emoji: Option<String>,
|
||||
#[derive(Debug, Clone, Deserialize, TS)]
|
||||
pub struct CreateNotificationRequest {
|
||||
/// Optional client-generated ID. If not provided, server generates one.
|
||||
/// Using client-generated IDs enables stable optimistic updates.
|
||||
#[ts(optional)]
|
||||
pub id: Option<Uuid>,
|
||||
pub organization_id: Uuid,
|
||||
pub seen: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, TS)]
|
||||
@@ -85,3 +45,13 @@ pub struct UpdateNotificationRequest {
|
||||
#[serde(default, deserialize_with = "some_if_present")]
|
||||
pub seen: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ListNotificationsQuery {
|
||||
pub organization_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, TS)]
|
||||
pub struct ListNotificationsResponse {
|
||||
pub notifications: Vec<Notification>,
|
||||
}
|
||||
|
||||
@@ -28,24 +28,6 @@ pub struct HandoffRedeemResponse {
|
||||
pub refresh_token: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, TS)]
|
||||
pub struct LocalLoginRequest {
|
||||
pub email: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, TS)]
|
||||
pub struct LocalLoginResponse {
|
||||
pub access_token: String,
|
||||
pub refresh_token: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, TS)]
|
||||
pub struct AuthMethodsResponse {
|
||||
pub local_auth_enabled: bool,
|
||||
pub oauth_providers: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, TS)]
|
||||
pub struct TokenRefreshRequest {
|
||||
pub refresh_token: String,
|
||||
@@ -78,10 +60,7 @@ pub struct ProfileResponse {
|
||||
#[serde(tag = "status", rename_all = "lowercase")]
|
||||
pub enum LoginStatus {
|
||||
LoggedOut,
|
||||
LoggedIn {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
profile: Option<ProfileResponse>,
|
||||
},
|
||||
LoggedIn { profile: ProfileResponse },
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, TS)]
|
||||
|
||||
@@ -23,21 +23,12 @@ pub struct PullRequest {
|
||||
pub merged_at: Option<DateTime<Utc>>,
|
||||
pub merge_commit_sha: Option<String>,
|
||||
pub target_branch_name: String,
|
||||
pub project_id: Uuid,
|
||||
#[deprecated(note = "use pull_request_issues join table instead")]
|
||||
pub issue_id: Uuid,
|
||||
pub workspace_id: Option<Uuid>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct PullRequestIssue {
|
||||
pub id: Uuid,
|
||||
pub pull_request_id: Uuid,
|
||||
pub issue_id: Uuid,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct ListPullRequestsQuery {
|
||||
pub issue_id: Uuid,
|
||||
@@ -47,35 +38,3 @@ pub struct ListPullRequestsQuery {
|
||||
pub struct ListPullRequestsResponse {
|
||||
pub pull_requests: Vec<PullRequest>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct ListPullRequestIssuesResponse {
|
||||
pub pull_request_issues: Vec<PullRequestIssue>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
|
||||
pub struct CreatePullRequestIssueRequest {
|
||||
/// Optional client-generated ID. If not provided, server generates one.
|
||||
/// Using client-generated IDs enables stable optimistic updates.
|
||||
#[ts(optional)]
|
||||
pub id: Option<Uuid>,
|
||||
pub issue_id: Uuid,
|
||||
pub url: String,
|
||||
pub number: i32,
|
||||
pub status: PullRequestStatus,
|
||||
pub merged_at: Option<DateTime<Utc>>,
|
||||
pub merge_commit_sha: Option<String>,
|
||||
pub target_branch_name: String,
|
||||
}
|
||||
|
||||
/// Request to update a PR status on the remote server.
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct UpdatePullRequestApiRequest {
|
||||
pub url: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub status: Option<PullRequestStatus>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub merged_at: Option<Option<DateTime<Utc>>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub merge_commit_sha: Option<Option<String>>,
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
[package]
|
||||
name = "client-info"
|
||||
version = "0.1.44"
|
||||
edition = "2024"
|
||||
@@ -1,43 +0,0 @@
|
||||
use std::{net::SocketAddr, sync::OnceLock};
|
||||
|
||||
/// Runtime information about the local server.
|
||||
#[derive(Clone)]
|
||||
pub struct ClientInfo {
|
||||
server_addr: OnceLock<SocketAddr>,
|
||||
preview_proxy_port: OnceLock<u16>,
|
||||
}
|
||||
|
||||
impl Default for ClientInfo {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ClientInfo {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
server_addr: OnceLock::new(),
|
||||
preview_proxy_port: OnceLock::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_server_addr(&self, addr: SocketAddr) -> Result<(), String> {
|
||||
self.server_addr
|
||||
.set(addr)
|
||||
.map_err(|_| "server address already set".to_string())
|
||||
}
|
||||
|
||||
pub fn get_server_addr(&self) -> Option<SocketAddr> {
|
||||
self.server_addr.get().copied()
|
||||
}
|
||||
|
||||
pub fn set_preview_proxy_port(&self, port: u16) -> Result<(), String> {
|
||||
self.preview_proxy_port
|
||||
.set(port)
|
||||
.map_err(|_| "preview proxy port already set".to_string())
|
||||
}
|
||||
|
||||
pub fn get_preview_proxy_port(&self) -> Option<u16> {
|
||||
self.preview_proxy_port.get().copied()
|
||||
}
|
||||
}
|
||||
68
crates/db/.sqlx/query-04e5a05c7cad438d39c4c8590410889ab1eefa7376d474a10c119d3f4d9143c7.json
generated
Normal file
68
crates/db/.sqlx/query-04e5a05c7cad438d39c4c8590410889ab1eefa7376d474a10c119d3f4d9143c7.json
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n execution_process_id as \"execution_process_id!: Uuid\",\n agent_session_id,\n agent_message_id,\n prompt,\n summary,\n seen as \"seen!: bool\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM coding_agent_turns\n WHERE agent_session_id = ?\n ORDER BY updated_at DESC\n LIMIT 1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "execution_process_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "agent_session_id",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "agent_message_id",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "prompt",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "summary",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "seen!: bool",
|
||||
"ordinal": 6,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "04e5a05c7cad438d39c4c8590410889ab1eefa7376d474a10c119d3f4d9143c7"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id AS \"id!: Uuid\",\n task_id AS \"task_id: Uuid\",\n container_ref,\n branch,\n setup_completed_at AS \"setup_completed_at: DateTime<Utc>\",\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n archived AS \"archived!: bool\",\n pinned AS \"pinned!: bool\",\n name,\n worktree_deleted AS \"worktree_deleted!: bool\"\n FROM workspaces\n WHERE id = $1",
|
||||
"query": "SELECT id AS \"id!: Uuid\",\n task_id AS \"task_id: Uuid\",\n container_ref,\n branch,\n agent_working_dir,\n setup_completed_at AS \"setup_completed_at: DateTime<Utc>\",\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n archived AS \"archived!: bool\",\n pinned AS \"pinned!: bool\",\n name\n FROM workspaces\n WHERE id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -24,39 +24,39 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"name": "agent_working_dir",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "archived!: bool",
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Integer"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pinned!: bool",
|
||||
"name": "archived!: bool",
|
||||
"ordinal": 8,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"name": "pinned!: bool",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "worktree_deleted!: bool",
|
||||
"name": "name",
|
||||
"ordinal": 10,
|
||||
"type_info": "Bool"
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -68,13 +68,13 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "766fa107de23b7e6c579223b083d916e252d422e2908c27f6718fcbd851de2c1"
|
||||
"hash": "08ecee6680d027f444d684111a7c0c84a4ed5cab0c0d015e09ab2cf5b84271f0"
|
||||
}
|
||||
12
crates/db/.sqlx/query-0a805c219c9028b2677bd94ccabd47916e60d26c1cede27e467f0ae91f6639ab.json
generated
Normal file
12
crates/db/.sqlx/query-0a805c219c9028b2677bd94ccabd47916e60d26c1cede27e467f0ae91f6639ab.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE migration_state\n SET status = 'migrated',\n remote_id = $3,\n error_message = NULL,\n updated_at = datetime('now', 'subsec')\n WHERE entity_type = $1 AND local_id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "0a805c219c9028b2677bd94ccabd47916e60d26c1cede27e467f0ae91f6639ab"
|
||||
}
|
||||
12
crates/db/.sqlx/query-0ac0d0f3826330836e3fd1bf57c42777eb489ac41a650f9361e6b563fc69bf35.json
generated
Normal file
12
crates/db/.sqlx/query-0ac0d0f3826330836e3fd1bf57c42777eb489ac41a650f9361e6b563fc69bf35.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE migration_state\n SET status = 'pending',\n error_message = NULL,\n updated_at = datetime('now', 'subsec')\n WHERE status = 'failed'",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "0ac0d0f3826330836e3fd1bf57c42777eb489ac41a650f9361e6b563fc69bf35"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "DELETE FROM pull_requests WHERE id = ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "0ee24d51e7557d9d6c9418a06156c03d7dd49dfe938194cd6951942dfd8f179d"
|
||||
}
|
||||
12
crates/db/.sqlx/query-0f90844fc62261ed140e02515ae464b940743113814507313c9fdc176000d1bf.json
generated
Normal file
12
crates/db/.sqlx/query-0f90844fc62261ed140e02515ae464b940743113814507313c9fdc176000d1bf.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE migration_state\n SET status = 'skipped',\n error_message = $3,\n updated_at = datetime('now', 'subsec')\n WHERE entity_type = $1 AND local_id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "0f90844fc62261ed140e02515ae464b940743113814507313c9fdc176000d1bf"
|
||||
}
|
||||
86
crates/db/.sqlx/query-1085d1f8107c7e16fc2058ef610918760d8d420f0fca97adecd76d698f6f3a51.json
generated
Normal file
86
crates/db/.sqlx/query-1085d1f8107c7e16fc2058ef610918760d8d420f0fca97adecd76d698f6f3a51.json
generated
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n workspace_id as \"workspace_id!: Uuid\",\n repo_id as \"repo_id!: Uuid\",\n merge_type as \"merge_type!: MergeType\",\n merge_commit,\n pr_number,\n pr_url,\n pr_status as \"pr_status?: MergeStatus\",\n pr_merged_at as \"pr_merged_at?: DateTime<Utc>\",\n pr_merge_commit_sha,\n target_branch_name as \"target_branch_name!: String\",\n created_at as \"created_at!: DateTime<Utc>\"\n FROM merges\n WHERE workspace_id = $1 AND repo_id = $2\n ORDER BY created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "merge_type!: MergeType",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 5,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_status?: MergeStatus",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merged_at?: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merge_commit_sha",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name!: String",
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "1085d1f8107c7e16fc2058ef610918760d8d420f0fca97adecd76d698f6f3a51"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id as \"id!: Uuid\",\n file_path as \"file_path!\",\n original_name as \"original_name!\",\n mime_type,\n size_bytes as \"size_bytes!\",\n hash as \"hash!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM attachments\n WHERE id = $1",
|
||||
"query": "SELECT id as \"id!: Uuid\",\n file_path as \"file_path!\",\n original_name as \"original_name!\",\n mime_type,\n size_bytes as \"size_bytes!\",\n hash as \"hash!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM images\n WHERE id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -58,5 +58,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "dc5d0ad507cbd962235c9e85c3e43f34c7c38eb2e08ab7899073010a6e77b37d"
|
||||
"hash": "1280290c78a1f55b3f0074ebcb61d855cab3e9be9ab0bc8c3f678adf4506b9cc"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT i.id as \"id!: Uuid\",\n i.file_path as \"file_path!\",\n i.original_name as \"original_name!\",\n i.mime_type,\n i.size_bytes as \"size_bytes!\",\n i.hash as \"hash!\",\n i.created_at as \"created_at!: DateTime<Utc>\",\n i.updated_at as \"updated_at!: DateTime<Utc>\"\n FROM attachments i\n LEFT JOIN workspace_attachments wa ON i.id = wa.attachment_id\n WHERE wa.workspace_id IS NULL",
|
||||
"query": "SELECT i.id as \"id!: Uuid\",\n i.file_path as \"file_path!\",\n i.original_name as \"original_name!\",\n i.mime_type,\n i.size_bytes as \"size_bytes!\",\n i.hash as \"hash!\",\n i.created_at as \"created_at!: DateTime<Utc>\",\n i.updated_at as \"updated_at!: DateTime<Utc>\"\n FROM images i\n LEFT JOIN workspace_images wi ON i.id = wi.image_id\n WHERE wi.workspace_id IS NULL",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -58,5 +58,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "df2f35912a8055dff6cb24c83ea67fc49b432f457961fa584c6a13389bfdcea5"
|
||||
"hash": "144e0cfb4810f51fe65577077e2f57b08eb278f2a819420a242aad5ab5be7944"
|
||||
}
|
||||
20
crates/db/.sqlx/query-167c1d13ee37ebe62cd2316feaf6b5354eb26d0a8fc16efb22827a5cde59a60e.json
generated
Normal file
20
crates/db/.sqlx/query-167c1d13ee37ebe62cd2316feaf6b5354eb26d0a8fc16efb22827a5cde59a60e.json
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT COUNT(1) as \"count!: i64\"\n FROM merges\n WHERE workspace_id = $1\n AND merge_type = 'pr'\n AND pr_status = 'open'",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "count!: i64",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "167c1d13ee37ebe62cd2316feaf6b5354eb26d0a8fc16efb22827a5cde59a60e"
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id,\n workspace_id AS \"workspace_id: Uuid\",\n repo_id AS \"repo_id: Uuid\",\n pr_url,\n pr_number,\n pr_status AS \"pr_status: MergeStatus\",\n target_branch_name,\n merged_at AS \"merged_at: DateTime<Utc>\",\n merge_commit_sha,\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n synced_at AS \"synced_at: DateTime<Utc>\"\n FROM pull_requests\n WHERE synced_at IS NULL OR synced_at < updated_at",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 4,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_status: MergeStatus",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merged_at: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit_sha",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 9,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 10,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "synced_at: DateTime<Utc>",
|
||||
"ordinal": 11,
|
||||
"type_info": "Datetime"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "1af7a606a64d9662d6edc4fbeaae0d53a4d657a6e29b2561e820085a2d9e3348"
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT COUNT(*) as \"count!: i64\"\n FROM execution_processes ep\n WHERE ep.session_id = $1\n AND ep.status = 'running'\n AND ep.run_reason = 'codingagent'",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "count!: i64",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "1b186dc075846fc1f7270a942afbf82a88806ee6ababdb437ab5e97ddd2122da"
|
||||
}
|
||||
44
crates/db/.sqlx/query-2462cbaa0c7bc7cc0d925b467bcc40ab4406977d1032e81371f7b2dda115f632.json
generated
Normal file
44
crates/db/.sqlx/query-2462cbaa0c7bc7cc0d925b467bcc40ab4406977d1032e81371f7b2dda115f632.json
generated
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT s.id AS \"id!: Uuid\",\n s.workspace_id AS \"workspace_id!: Uuid\",\n s.executor,\n s.created_at AS \"created_at!: DateTime<Utc>\",\n s.updated_at AS \"updated_at!: DateTime<Utc>\"\n FROM sessions s\n LEFT JOIN (\n SELECT ep.session_id, MAX(ep.created_at) as last_used\n FROM execution_processes ep\n WHERE ep.run_reason != 'devserver' AND ep.dropped = FALSE\n GROUP BY ep.session_id\n ) latest_ep ON s.id = latest_ep.session_id\n WHERE s.workspace_id = $1\n ORDER BY COALESCE(latest_ep.last_used, s.created_at) DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "executor",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "2462cbaa0c7bc7cc0d925b467bcc40ab4406977d1032e81371f7b2dda115f632"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id as \"id!: Uuid\",\n file_path as \"file_path!\",\n original_name as \"original_name!\",\n mime_type,\n size_bytes as \"size_bytes!\",\n hash as \"hash!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM attachments\n WHERE hash = $1",
|
||||
"query": "SELECT id as \"id!: Uuid\",\n file_path as \"file_path!\",\n original_name as \"original_name!\",\n mime_type,\n size_bytes as \"size_bytes!\",\n hash as \"hash!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM images\n WHERE hash = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -58,5 +58,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "04f17449e3e12785affab91e4eab308103491e34c022199b7b060e04fa8aed0f"
|
||||
"hash": "2827716b6501cc3c44ec50ae1a3d90f759cc3940c8fe6ffe383d0f741e3a2a78"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE pull_requests SET pr_status = ?, merged_at = ?, merge_commit_sha = ?, updated_at = ?, synced_at = NULL WHERE pr_url = ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 5
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2948ec0606a39ee67bdbaf4f2cf82592448a1d91a66d7d89cf7204f71f706274"
|
||||
}
|
||||
20
crates/db/.sqlx/query-29cc3aa8d0ad5deda94494402500a4125e29381d63f18ef083cc4da95e2c5db5.json
generated
Normal file
20
crates/db/.sqlx/query-29cc3aa8d0ad5deda94494402500a4125e29381d63f18ef083cc4da95e2c5db5.json
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT w.id as \"workspace_id!: Uuid\"\n FROM workspaces w\n WHERE w.container_ref = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "29cc3aa8d0ad5deda94494402500a4125e29381d63f18ef083cc4da95e2c5db5"
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT w.name AS \"name: String\"\n FROM workspaces w\n JOIN workspace_repos wr ON wr.workspace_id = w.id\n WHERE wr.repo_id = $1\n AND w.archived = FALSE",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "name: String",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "2c71bf4dd5683e0dedf2341e52880ff2c0765659d3cf53d62faa54adc91071dd"
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id,\n workspace_id AS \"workspace_id: Uuid\",\n repo_id AS \"repo_id: Uuid\",\n pr_url,\n pr_number,\n pr_status AS \"pr_status: MergeStatus\",\n target_branch_name,\n merged_at AS \"merged_at: DateTime<Utc>\",\n merge_commit_sha,\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n synced_at AS \"synced_at: DateTime<Utc>\"\n FROM pull_requests\n WHERE workspace_id = $1 AND repo_id = $2\n ORDER BY created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 4,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_status: MergeStatus",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merged_at: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit_sha",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 9,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 10,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "synced_at: DateTime<Utc>",
|
||||
"ordinal": 11,
|
||||
"type_info": "Datetime"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "32c74a54fdd72a6b167583228f2c30944837b7cc29c9cc4acfbb4f047cea7118"
|
||||
}
|
||||
68
crates/db/.sqlx/query-33f23656ba343bd75a88b0fadf2a4ba01eda330f9b549e625e27701e3b0b5a31.json
generated
Normal file
68
crates/db/.sqlx/query-33f23656ba343bd75a88b0fadf2a4ba01eda330f9b549e625e27701e3b0b5a31.json
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n entity_type as \"entity_type!: EntityType\",\n local_id as \"local_id!: Uuid\",\n remote_id as \"remote_id: Uuid\",\n status as \"status!: MigrationStatus\",\n error_message,\n attempt_count as \"attempt_count!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM migration_state\n WHERE entity_type = $1 AND status = 'pending'\n ORDER BY created_at ASC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "entity_type!: EntityType",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "local_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "remote_id: Uuid",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "status!: MigrationStatus",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "error_message",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "attempt_count!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "33f23656ba343bd75a88b0fadf2a4ba01eda330f9b549e625e27701e3b0b5a31"
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id as \"id!: Uuid\",\n container_ref as \"container_ref!\"\n FROM workspaces\n WHERE container_ref IS NOT NULL",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "container_ref!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "3634e2bab8fef106721bb64a791edd81d3d49eb34fbabd34e4feadfb5f229a6e"
|
||||
}
|
||||
86
crates/db/.sqlx/query-3ace1ee8dba0669400d69891912b86823e41ca643092d990b12c1a6160112427.json
generated
Normal file
86
crates/db/.sqlx/query-3ace1ee8dba0669400d69891912b86823e41ca643092d990b12c1a6160112427.json
generated
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n m.id as \"id!: Uuid\",\n m.workspace_id as \"workspace_id!: Uuid\",\n m.repo_id as \"repo_id!: Uuid\",\n m.merge_type as \"merge_type!: MergeType\",\n m.merge_commit,\n m.pr_number,\n m.pr_url,\n m.pr_status as \"pr_status?: MergeStatus\",\n m.pr_merged_at as \"pr_merged_at?: DateTime<Utc>\",\n m.pr_merge_commit_sha,\n m.target_branch_name as \"target_branch_name!: String\",\n m.created_at as \"created_at!: DateTime<Utc>\"\n FROM merges m\n INNER JOIN (\n SELECT workspace_id, MAX(created_at) as max_created_at\n FROM merges\n WHERE merge_type = 'pr'\n GROUP BY workspace_id\n ) latest ON m.workspace_id = latest.workspace_id\n AND m.created_at = latest.max_created_at\n INNER JOIN workspaces w ON m.workspace_id = w.id\n WHERE m.merge_type = 'pr' AND w.archived = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "merge_type!: MergeType",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 5,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_status?: MergeStatus",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merged_at?: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merge_commit_sha",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name!: String",
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3ace1ee8dba0669400d69891912b86823e41ca643092d990b12c1a6160112427"
|
||||
}
|
||||
86
crates/db/.sqlx/query-3d85256618729c1c0bf2758ffab9cdb4ec2af0751e3a37db4009c02f95f6f556.json
generated
Normal file
86
crates/db/.sqlx/query-3d85256618729c1c0bf2758ffab9cdb4ec2af0751e3a37db4009c02f95f6f556.json
generated
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO merges (\n id, workspace_id, repo_id, merge_type, pr_number, pr_url, pr_status, created_at, target_branch_name\n ) VALUES ($1, $2, $3, 'pr', $4, $5, 'open', $6, $7)\n RETURNING\n id as \"id!: Uuid\",\n workspace_id as \"workspace_id!: Uuid\",\n repo_id as \"repo_id!: Uuid\",\n merge_type as \"merge_type!: MergeType\",\n merge_commit,\n pr_number,\n pr_url,\n pr_status as \"pr_status?: MergeStatus\",\n pr_merged_at as \"pr_merged_at?: DateTime<Utc>\",\n pr_merge_commit_sha,\n created_at as \"created_at!: DateTime<Utc>\",\n target_branch_name as \"target_branch_name!: String\"\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "merge_type!: MergeType",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 5,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_status?: MergeStatus",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merged_at?: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merge_commit_sha",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name!: String",
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 7
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3d85256618729c1c0bf2758ffab9cdb4ec2af0751e3a37db4009c02f95f6f556"
|
||||
}
|
||||
80
crates/db/.sqlx/query-424ee349862b29e2b21267e5266065b036f03be70161ccf3c299174df9f8b96e.json
generated
Normal file
80
crates/db/.sqlx/query-424ee349862b29e2b21267e5266065b036f03be70161ccf3c299174df9f8b96e.json
generated
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n w.id as \"id!: Uuid\",\n w.task_id as \"task_id: Uuid\",\n w.container_ref,\n w.branch as \"branch!\",\n w.agent_working_dir,\n w.setup_completed_at as \"setup_completed_at: DateTime<Utc>\",\n w.created_at as \"created_at!: DateTime<Utc>\",\n w.updated_at as \"updated_at!: DateTime<Utc>\",\n w.archived as \"archived!: bool\",\n w.pinned as \"pinned!: bool\",\n w.name\n FROM workspaces w\n LEFT JOIN sessions s ON w.id = s.workspace_id\n LEFT JOIN execution_processes ep ON s.id = ep.session_id AND ep.completed_at IS NOT NULL\n WHERE w.container_ref IS NOT NULL\n AND w.id NOT IN (\n SELECT DISTINCT s2.workspace_id\n FROM sessions s2\n JOIN execution_processes ep2 ON s2.id = ep2.session_id\n WHERE ep2.completed_at IS NULL\n )\n GROUP BY w.id, w.container_ref, w.updated_at\n HAVING datetime('now', 'localtime',\n CASE\n WHEN w.archived = 1\n THEN '-1 hours'\n ELSE '-72 hours'\n END\n ) > datetime(\n MAX(\n max(\n datetime(w.updated_at),\n datetime(ep.completed_at)\n )\n )\n )\n ORDER BY MAX(\n CASE\n WHEN ep.completed_at IS NOT NULL THEN ep.completed_at\n ELSE w.updated_at\n END\n ) ASC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "task_id: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "container_ref",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "branch!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "agent_working_dir",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "archived!: bool",
|
||||
"ordinal": 8,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pinned!: bool",
|
||||
"ordinal": 9,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "424ee349862b29e2b21267e5266065b036f03be70161ccf3c299174df9f8b96e"
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT s.id AS \"id!: Uuid\",\n s.workspace_id AS \"workspace_id!: Uuid\",\n s.name,\n s.executor,\n s.agent_working_dir,\n s.created_at AS \"created_at!: DateTime<Utc>\",\n s.updated_at AS \"updated_at!: DateTime<Utc>\"\n FROM sessions s\n LEFT JOIN (\n SELECT ep.session_id, MAX(ep.created_at) as last_used\n FROM execution_processes ep\n WHERE ep.run_reason != 'devserver' AND ep.dropped = FALSE\n GROUP BY ep.session_id\n ) latest_ep ON s.id = latest_ep.session_id\n WHERE s.workspace_id = $1\n ORDER BY COALESCE(latest_ep.last_used, s.created_at) DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "executor",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "agent_working_dir",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "4506eeeb85b49f00143a9d23636c976159e1c72c9cfce005599c5eb52dc15095"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "DELETE FROM attachments WHERE id = $1",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "4ac35216ead7e5be9cc2de504a06b6e375e23ca2ed14493ec991f53e458a6a34"
|
||||
}
|
||||
86
crates/db/.sqlx/query-4b59b958807be54c7c9949d96ced96e4ab1498f1056e7d0d7956aff46352d90f.json
generated
Normal file
86
crates/db/.sqlx/query-4b59b958807be54c7c9949d96ced96e4ab1498f1056e7d0d7956aff46352d90f.json
generated
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n workspace_id as \"workspace_id!: Uuid\",\n repo_id as \"repo_id!: Uuid\",\n merge_type as \"merge_type!: MergeType\",\n merge_commit,\n pr_number,\n pr_url,\n pr_status as \"pr_status?: MergeStatus\",\n pr_merged_at as \"pr_merged_at?: DateTime<Utc>\",\n pr_merge_commit_sha,\n target_branch_name as \"target_branch_name!: String\",\n created_at as \"created_at!: DateTime<Utc>\"\n FROM merges\n WHERE workspace_id = $1\n ORDER BY created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "merge_type!: MergeType",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 5,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_status?: MergeStatus",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merged_at?: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merge_commit_sha",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name!: String",
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "4b59b958807be54c7c9949d96ced96e4ab1498f1056e7d0d7956aff46352d90f"
|
||||
}
|
||||
12
crates/db/.sqlx/query-4d84b308a2cc7677da65111d080bf02e5e35c052048360d3dbea656bbbcd3edb.json
generated
Normal file
12
crates/db/.sqlx/query-4d84b308a2cc7677da65111d080bf02e5e35c052048360d3dbea656bbbcd3edb.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE execution_process_repo_states\n SET merge_commit = $1, updated_at = $2\n WHERE execution_process_id = $3\n AND repo_id = $4",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "4d84b308a2cc7677da65111d080bf02e5e35c052048360d3dbea656bbbcd3edb"
|
||||
}
|
||||
68
crates/db/.sqlx/query-517fb82570b9624e166696af53963ec499966562b23b5833fc4ca4cf43bcaccc.json
generated
Normal file
68
crates/db/.sqlx/query-517fb82570b9624e166696af53963ec499966562b23b5833fc4ca4cf43bcaccc.json
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n entity_type as \"entity_type!: EntityType\",\n local_id as \"local_id!: Uuid\",\n remote_id as \"remote_id: Uuid\",\n status as \"status!: MigrationStatus\",\n error_message,\n attempt_count as \"attempt_count!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM migration_state\n WHERE entity_type = $1\n ORDER BY created_at ASC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "entity_type!: EntityType",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "local_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "remote_id: Uuid",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "status!: MigrationStatus",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "error_message",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "attempt_count!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "517fb82570b9624e166696af53963ec499966562b23b5833fc4ca4cf43bcaccc"
|
||||
}
|
||||
86
crates/db/.sqlx/query-570f62a32921c4a9a7e4e1006e9b31c4c58e69ab8681d76dfe9b184ff1e0bc65.json
generated
Normal file
86
crates/db/.sqlx/query-570f62a32921c4a9a7e4e1006e9b31c4c58e69ab8681d76dfe9b184ff1e0bc65.json
generated
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n workspace_id as \"workspace_id!: Uuid\",\n repo_id as \"repo_id!: Uuid\",\n merge_type as \"merge_type!: MergeType\",\n merge_commit,\n pr_number,\n pr_url,\n pr_status as \"pr_status?: MergeStatus\",\n pr_merged_at as \"pr_merged_at?: DateTime<Utc>\",\n pr_merge_commit_sha,\n created_at as \"created_at!: DateTime<Utc>\",\n target_branch_name as \"target_branch_name!: String\"\n FROM merges\n WHERE merge_type = 'pr'\n ORDER BY created_at ASC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "merge_type!: MergeType",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 5,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_status?: MergeStatus",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merged_at?: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_merge_commit_sha",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 10,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name!: String",
|
||||
"ordinal": 11,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "570f62a32921c4a9a7e4e1006e9b31c4c58e69ab8681d76dfe9b184ff1e0bc65"
|
||||
}
|
||||
12
crates/db/.sqlx/query-5785a10c3d51ff9b001aa455f6296a4dcba61cec700a4b72031c5c643b273938.json
generated
Normal file
12
crates/db/.sqlx/query-5785a10c3d51ff9b001aa455f6296a4dcba61cec700a4b72031c5c643b273938.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE merges\n SET pr_status = $1,\n pr_merge_commit_sha = $2,\n pr_merged_at = $3\n WHERE id = $4",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "5785a10c3d51ff9b001aa455f6296a4dcba61cec700a4b72031c5c643b273938"
|
||||
}
|
||||
20
crates/db/.sqlx/query-606016bf31cf0abd87d7eb95ea99d7c8c014523cb02e482d608299ceefaeffc5.json
generated
Normal file
20
crates/db/.sqlx/query-606016bf31cf0abd87d7eb95ea99d7c8c014523cb02e482d608299ceefaeffc5.json
generated
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT EXISTS(\n SELECT 1 FROM coding_agent_turns cat\n JOIN execution_processes ep ON cat.execution_process_id = ep.id\n JOIN sessions s ON ep.session_id = s.id\n WHERE s.workspace_id = $1 AND cat.seen = 0\n ) as \"has_unseen!: bool\"",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "has_unseen!: bool",
|
||||
"ordinal": 0,
|
||||
"type_info": "Integer"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "606016bf31cf0abd87d7eb95ea99d7c8c014523cb02e482d608299ceefaeffc5"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT i.id as \"id!: Uuid\",\n i.file_path as \"file_path!\",\n i.original_name as \"original_name!\",\n i.mime_type,\n i.size_bytes as \"size_bytes!\",\n i.hash as \"hash!\",\n i.created_at as \"created_at!: DateTime<Utc>\",\n i.updated_at as \"updated_at!: DateTime<Utc>\"\n FROM attachments i\n JOIN workspace_attachments wa ON i.id = wa.attachment_id\n WHERE wa.workspace_id = $1\n ORDER BY wa.created_at",
|
||||
"query": "SELECT i.id as \"id!: Uuid\",\n i.file_path as \"file_path!\",\n i.original_name as \"original_name!\",\n i.mime_type,\n i.size_bytes as \"size_bytes!\",\n i.hash as \"hash!\",\n i.created_at as \"created_at!: DateTime<Utc>\",\n i.updated_at as \"updated_at!: DateTime<Utc>\"\n FROM images i\n JOIN workspace_images wi ON i.id = wi.image_id\n WHERE wi.workspace_id = $1\n ORDER BY wi.created_at",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -58,5 +58,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "586d5ab95899967c8a8f74996c4a598a73661823bc2bcb240cebb7cd0533abb6"
|
||||
"hash": "60e47682fe6fc150ee737176c9221ab1958595e92dc0fc5928688af847ab30ce"
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n t.id,\n t.workspace_id AS \"workspace_id: Uuid\",\n t.repo_id AS \"repo_id: Uuid\",\n t.pr_url,\n t.pr_number,\n t.pr_status AS \"pr_status: MergeStatus\",\n t.target_branch_name,\n t.merged_at AS \"merged_at: DateTime<Utc>\",\n t.merge_commit_sha,\n t.created_at AS \"created_at!: DateTime<Utc>\",\n t.updated_at AS \"updated_at!: DateTime<Utc>\",\n t.synced_at AS \"synced_at: DateTime<Utc>\"\n FROM pull_requests t\n INNER JOIN (\n SELECT workspace_id, MAX(created_at) as max_created_at\n FROM pull_requests\n WHERE workspace_id IS NOT NULL\n GROUP BY workspace_id\n ) latest ON t.workspace_id = latest.workspace_id AND t.created_at = latest.max_created_at\n INNER JOIN workspaces w ON t.workspace_id = w.id\n WHERE t.workspace_id IS NOT NULL AND w.archived = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 4,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_status: MergeStatus",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merged_at: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit_sha",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 9,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 10,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "synced_at: DateTime<Utc>",
|
||||
"ordinal": 11,
|
||||
"type_info": "Datetime"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "64cdb811a6d15a483fc0413dc49ba8aa093b1892831699c456afe0507ac51aa3"
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id AS \"id!: Uuid\",\n workspace_id AS \"workspace_id!: Uuid\",\n repo_id AS \"repo_id!: Uuid\",\n merge_commit,\n target_branch_name,\n created_at AS \"created_at!: DateTime<Utc>\"\n FROM merges\n WHERE workspace_id = ? AND merge_type = 'direct'\n ORDER BY created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "67a7192158ad406cf8b97165c46a602330e807ed2757497e483295ea21952f1f"
|
||||
}
|
||||
68
crates/db/.sqlx/query-686810c5271e1d44042b6ea2c6cc434eb2e3f5d3540c97d703c34dd4e978c690.json
generated
Normal file
68
crates/db/.sqlx/query-686810c5271e1d44042b6ea2c6cc434eb2e3f5d3540c97d703c34dd4e978c690.json
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n entity_type as \"entity_type!: EntityType\",\n local_id as \"local_id!: Uuid\",\n remote_id as \"remote_id: Uuid\",\n status as \"status!: MigrationStatus\",\n error_message,\n attempt_count as \"attempt_count!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM migration_state\n WHERE entity_type = $1 AND local_id = $2",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "entity_type!: EntityType",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "local_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "remote_id: Uuid",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "status!: MigrationStatus",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "error_message",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "attempt_count!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "686810c5271e1d44042b6ea2c6cc434eb2e3f5d3540c97d703c34dd4e978c690"
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id AS \"id!: Uuid\",\n workspace_id AS \"workspace_id!: Uuid\",\n repo_id AS \"repo_id!: Uuid\",\n merge_commit,\n target_branch_name,\n created_at AS \"created_at!: DateTime<Utc>\"\n FROM merges\n WHERE workspace_id = ? AND repo_id = ? AND merge_type = 'direct'\n ORDER BY created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "687a386ec0c65676bcd9d1ced30549e4c2a3d2bdb63a0a5623027e50aa6e4389"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO workspace_attachments (id, workspace_id, attachment_id)\n SELECT $1, $2, $3\n WHERE NOT EXISTS (\n SELECT 1 FROM workspace_attachments WHERE workspace_id = $2 AND attachment_id = $3\n )",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "6ae5eb2719382d4d081ee17dbd5de654c156b06e2af4ddfb917d36002146be5b"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT COUNT(1) AS \"count!: i64\" FROM pull_requests WHERE workspace_id = ? AND pr_status = 'open'",
|
||||
"query": "SELECT COUNT(*) as \"count!: i64\" FROM workspaces",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -10,11 +10,11 @@
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "21c7a9f62322212a5f6b923bb410c25ac06e6a0c857d910d93fb80ab77fc9b35"
|
||||
"hash": "70b21c5c0a2ba5c21c9c1132f14a68c02a8a2cd555caea74e57a0aeb206770d3"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id AS \"id!: Uuid\",\n task_id AS \"task_id: Uuid\",\n container_ref,\n branch,\n setup_completed_at AS \"setup_completed_at: DateTime<Utc>\",\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n archived AS \"archived!: bool\",\n pinned AS \"pinned!: bool\",\n name,\n worktree_deleted AS \"worktree_deleted!: bool\"\n FROM workspaces\n ORDER BY created_at DESC",
|
||||
"query": "SELECT id AS \"id!: Uuid\",\n task_id AS \"task_id: Uuid\",\n container_ref,\n branch,\n agent_working_dir,\n setup_completed_at AS \"setup_completed_at: DateTime<Utc>\",\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n archived AS \"archived!: bool\",\n pinned AS \"pinned!: bool\",\n name\n FROM workspaces\n ORDER BY created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -24,39 +24,39 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"name": "agent_working_dir",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "archived!: bool",
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Integer"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pinned!: bool",
|
||||
"name": "archived!: bool",
|
||||
"ordinal": 8,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"name": "pinned!: bool",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "worktree_deleted!: bool",
|
||||
"name": "name",
|
||||
"ordinal": 10,
|
||||
"type_info": "Bool"
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -68,13 +68,13 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "64f31710ab7ba14047f31cce44ad36c60a53624f9bcb03a5eaff5d61ca8cc9cf"
|
||||
"hash": "72c04c3a56fc9dc0b08ada7c4260d7813f4c02005bc0a0935c8c7716c51c5047"
|
||||
}
|
||||
68
crates/db/.sqlx/query-7364150098bec681451c43762117a1f5c5b4e27f5f65186c3cc16092b3491c37.json
generated
Normal file
68
crates/db/.sqlx/query-7364150098bec681451c43762117a1f5c5b4e27f5f65186c3cc16092b3491c37.json
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO migration_state (id, entity_type, local_id)\n VALUES ($1, $2, $3)\n ON CONFLICT (entity_type, local_id) DO UPDATE SET\n updated_at = datetime('now', 'subsec')\n RETURNING\n id as \"id!: Uuid\",\n entity_type as \"entity_type!: EntityType\",\n local_id as \"local_id!: Uuid\",\n remote_id as \"remote_id: Uuid\",\n status as \"status!: MigrationStatus\",\n error_message,\n attempt_count as \"attempt_count!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "entity_type!: EntityType",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "local_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "remote_id: Uuid",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "status!: MigrationStatus",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "error_message",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "attempt_count!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "7364150098bec681451c43762117a1f5c5b4e27f5f65186c3cc16092b3491c37"
|
||||
}
|
||||
68
crates/db/.sqlx/query-7807cb09da72c5a1e35bf4f4da1bea1743a578588e72444ede98f5f969af08c1.json
generated
Normal file
68
crates/db/.sqlx/query-7807cb09da72c5a1e35bf4f4da1bea1743a578588e72444ede98f5f969af08c1.json
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n entity_type as \"entity_type!: EntityType\",\n local_id as \"local_id!: Uuid\",\n remote_id as \"remote_id: Uuid\",\n status as \"status!: MigrationStatus\",\n error_message,\n attempt_count as \"attempt_count!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM migration_state\n ORDER BY created_at ASC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "entity_type!: EntityType",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "local_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "remote_id: Uuid",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "status!: MigrationStatus",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "error_message",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "attempt_count!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "7807cb09da72c5a1e35bf4f4da1bea1743a578588e72444ede98f5f969af08c1"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id AS \"id!: Uuid\",\n workspace_id AS \"workspace_id!: Uuid\",\n name,\n executor,\n agent_working_dir,\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\"\n FROM sessions\n WHERE id = $1",
|
||||
"query": "SELECT id AS \"id!: Uuid\",\n workspace_id AS \"workspace_id!: Uuid\",\n executor,\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\"\n FROM sessions\n WHERE id = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -14,28 +14,18 @@
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"name": "executor",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "executor",
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "agent_working_dir",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
@@ -46,11 +36,9 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "db39f7ab7391c1289299e7f8aa7e1f642874eed0179e91a9558f9df534db797c"
|
||||
"hash": "7811b89c22f9d9a440d84c347b1824738c8d01ce7979d791778320b92ccf7a30"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "DELETE FROM repos WHERE id = $1",
|
||||
"query": "DELETE FROM images WHERE id = $1",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -8,5 +8,5 @@
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "3a9148e9e914d644d4d82a1c2dc8bd0e093d4f4c638afa7fd8f5211892fb6d84"
|
||||
"hash": "79b35e39d668ad2285b3a05c15d5243cc91d35e03104d222488c7e27b8bbb569"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO workspaces (id, task_id, container_ref, branch, setup_completed_at, name)\n VALUES ($1, $2, $3, $4, $5, $6)\n RETURNING id as \"id!: Uuid\", task_id as \"task_id: Uuid\", container_ref, branch, setup_completed_at as \"setup_completed_at: DateTime<Utc>\", created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\", archived as \"archived!: bool\", pinned as \"pinned!: bool\", name, worktree_deleted as \"worktree_deleted!: bool\"",
|
||||
"query": "INSERT INTO workspaces (id, task_id, container_ref, branch, agent_working_dir, setup_completed_at)\n VALUES ($1, $2, $3, $4, $5, $6)\n RETURNING id as \"id!: Uuid\", task_id as \"task_id: Uuid\", container_ref, branch, agent_working_dir, setup_completed_at as \"setup_completed_at: DateTime<Utc>\", created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\", archived as \"archived!: bool\", pinned as \"pinned!: bool\", name",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -24,39 +24,39 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"name": "agent_working_dir",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "archived!: bool",
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Integer"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pinned!: bool",
|
||||
"name": "archived!: bool",
|
||||
"ordinal": 8,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"name": "pinned!: bool",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "worktree_deleted!: bool",
|
||||
"name": "name",
|
||||
"ordinal": 10,
|
||||
"type_info": "Bool"
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -68,13 +68,13 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "7410e8128e63af1c3127e833accee637e65f7efcd9111ecb891587294042129c"
|
||||
"hash": "7d08c4f085511474324aa4f4e291cf80bd75a439fdb8648a2646304cee93da25"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE pull_requests SET synced_at = ? WHERE id = ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "8076c3d62eba1cdf2a050c9d61dc20ef2fc3e24b0830d1e20099a42ae78333d0"
|
||||
}
|
||||
12
crates/db/.sqlx/query-83cff8501927f930b9db7c131051c3103a74b1ca12d936cf523594945020c665.json
generated
Normal file
12
crates/db/.sqlx/query-83cff8501927f930b9db7c131051c3103a74b1ca12d936cf523594945020c665.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE workspaces SET container_ref = NULL, updated_at = datetime('now') WHERE id = ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "83cff8501927f930b9db7c131051c3103a74b1ca12d936cf523594945020c665"
|
||||
}
|
||||
68
crates/db/.sqlx/query-84ee994f0aad005cf62ca318eb20ae29d218a72cdd1fadf2a5ae399b0719ca19.json
generated
Normal file
68
crates/db/.sqlx/query-84ee994f0aad005cf62ca318eb20ae29d218a72cdd1fadf2a5ae399b0719ca19.json
generated
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id as \"id!: Uuid\",\n entity_type as \"entity_type!: EntityType\",\n local_id as \"local_id!: Uuid\",\n remote_id as \"remote_id: Uuid\",\n status as \"status!: MigrationStatus\",\n error_message,\n attempt_count as \"attempt_count!\",\n created_at as \"created_at!: DateTime<Utc>\",\n updated_at as \"updated_at!: DateTime<Utc>\"\n FROM migration_state\n WHERE status = $1\n ORDER BY created_at ASC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "entity_type!: EntityType",
|
||||
"ordinal": 1,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "local_id!: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "remote_id: Uuid",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "status!: MigrationStatus",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "error_message",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "attempt_count!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "84ee994f0aad005cf62ca318eb20ae29d218a72cdd1fadf2a5ae399b0719ca19"
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n w.id as \"id!: Uuid\",\n w.task_id as \"task_id: Uuid\",\n w.container_ref,\n w.branch as \"branch!\",\n w.setup_completed_at as \"setup_completed_at: DateTime<Utc>\",\n w.created_at as \"created_at!: DateTime<Utc>\",\n w.updated_at as \"updated_at!: DateTime<Utc>\",\n w.archived as \"archived!: bool\",\n w.pinned as \"pinned!: bool\",\n w.name,\n w.worktree_deleted as \"worktree_deleted!: bool\"\n FROM workspaces w\n LEFT JOIN sessions s ON w.id = s.workspace_id\n LEFT JOIN execution_processes ep ON s.id = ep.session_id AND ep.completed_at IS NOT NULL\n WHERE w.container_ref IS NOT NULL\n AND w.worktree_deleted = FALSE\n AND w.id NOT IN (\n SELECT DISTINCT s2.workspace_id\n FROM sessions s2\n JOIN execution_processes ep2 ON s2.id = ep2.session_id\n WHERE ep2.completed_at IS NULL\n )\n GROUP BY w.id, w.container_ref, w.updated_at\n HAVING datetime('now', 'localtime',\n CASE\n WHEN w.archived = 1\n THEN '-1 hours'\n ELSE '-72 hours'\n END\n ) > datetime(\n MAX(\n max(\n datetime(w.updated_at),\n datetime(ep.completed_at)\n )\n )\n )\n ORDER BY MAX(\n CASE\n WHEN ep.completed_at IS NOT NULL THEN ep.completed_at\n ELSE w.updated_at\n END\n ) ASC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "task_id: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "container_ref",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "branch!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "archived!: bool",
|
||||
"ordinal": 7,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pinned!: bool",
|
||||
"ordinal": 8,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "worktree_deleted!: bool",
|
||||
"ordinal": 10,
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "91810eeed4804827717a182ad1b61c641648e2659100f43ef9504fc60e5d244e"
|
||||
}
|
||||
44
crates/db/.sqlx/query-91d94506317abcd36e0da72066a5d31c3ec52530661a96c8231912c5b2a683f8.json
generated
Normal file
44
crates/db/.sqlx/query-91d94506317abcd36e0da72066a5d31c3ec52530661a96c8231912c5b2a683f8.json
generated
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT s.id AS \"id!: Uuid\",\n s.workspace_id AS \"workspace_id!: Uuid\",\n s.executor,\n s.created_at AS \"created_at!: DateTime<Utc>\",\n s.updated_at AS \"updated_at!: DateTime<Utc>\"\n FROM sessions s\n LEFT JOIN (\n SELECT ep.session_id, MAX(ep.created_at) as last_used\n FROM execution_processes ep\n WHERE ep.run_reason != 'devserver' AND ep.dropped = FALSE\n GROUP BY ep.session_id\n ) latest_ep ON s.id = latest_ep.session_id\n WHERE s.workspace_id = $1\n ORDER BY COALESCE(latest_ep.last_used, s.created_at) DESC\n LIMIT 1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "executor",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "91d94506317abcd36e0da72066a5d31c3ec52530661a96c8231912c5b2a683f8"
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT s.id AS \"id!: Uuid\",\n s.workspace_id AS \"workspace_id!: Uuid\",\n s.name,\n s.executor,\n s.agent_working_dir,\n s.created_at AS \"created_at!: DateTime<Utc>\",\n s.updated_at AS \"updated_at!: DateTime<Utc>\"\n FROM sessions s\n LEFT JOIN (\n SELECT ep.session_id, MAX(ep.created_at) as last_used\n FROM execution_processes ep\n WHERE ep.run_reason != 'devserver' AND ep.dropped = FALSE\n GROUP BY ep.session_id\n ) latest_ep ON s.id = latest_ep.session_id\n WHERE s.workspace_id = $1\n ORDER BY COALESCE(latest_ep.last_used, s.created_at) DESC\n LIMIT 1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "executor",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "agent_working_dir",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "93efe07b91d232fc0c371be8ee618ba6ccfd6930454fc11845d5dfc2ba0bad62"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO attachments (id, file_path, original_name, mime_type, size_bytes, hash)\n VALUES ($1, $2, $3, $4, $5, $6)\n RETURNING id as \"id!: Uuid\", \n file_path as \"file_path!\", \n original_name as \"original_name!\", \n mime_type,\n size_bytes as \"size_bytes!\",\n hash as \"hash!\",\n created_at as \"created_at!: DateTime<Utc>\", \n updated_at as \"updated_at!: DateTime<Utc>\"",
|
||||
"query": "INSERT INTO images (id, file_path, original_name, mime_type, size_bytes, hash)\n VALUES ($1, $2, $3, $4, $5, $6)\n RETURNING id as \"id!: Uuid\", \n file_path as \"file_path!\", \n original_name as \"original_name!\", \n mime_type,\n size_bytes as \"size_bytes!\",\n hash as \"hash!\",\n created_at as \"created_at!: DateTime<Utc>\", \n updated_at as \"updated_at!: DateTime<Utc>\"",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -58,5 +58,5 @@
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "4b952fb779fbcf70bd402b6bcc0eec07b75879333614b8ef98e5b8073ad66ca6"
|
||||
"hash": "943c19a516ecc2060133457fc8104ad612dfb872f616cd47bb900646b7f5af37"
|
||||
}
|
||||
12
crates/db/.sqlx/query-9747ebaebd562d65f0c333b0f5efc74fa63ab9fcb35a43f75f57da3fcb9a2588.json
generated
Normal file
12
crates/db/.sqlx/query-9747ebaebd562d65f0c333b0f5efc74fa63ab9fcb35a43f75f57da3fcb9a2588.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO execution_process_logs (execution_id, logs, byte_size, inserted_at)\n VALUES ($1, $2, $3, datetime('now', 'subsec'))",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "9747ebaebd562d65f0c333b0f5efc74fa63ab9fcb35a43f75f57da3fcb9a2588"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO merges (id, workspace_id, repo_id, merge_type, merge_commit, created_at, target_branch_name)\n VALUES (?, ?, ?, 'direct', ?, ?, ?)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 6
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "9ab0fedd6e06a0372797e66c9353dd807e85e059520f20db4b03d9a27bb3efb7"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT id AS \"id!: Uuid\",\n task_id AS \"task_id: Uuid\",\n container_ref,\n branch,\n setup_completed_at AS \"setup_completed_at: DateTime<Utc>\",\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n archived AS \"archived!: bool\",\n pinned AS \"pinned!: bool\",\n name,\n worktree_deleted AS \"worktree_deleted!: bool\"\n FROM workspaces\n WHERE rowid = $1",
|
||||
"query": "SELECT id AS \"id!: Uuid\",\n task_id AS \"task_id: Uuid\",\n container_ref,\n branch,\n agent_working_dir,\n setup_completed_at AS \"setup_completed_at: DateTime<Utc>\",\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n archived AS \"archived!: bool\",\n pinned AS \"pinned!: bool\",\n name\n FROM workspaces\n WHERE rowid = $1",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
@@ -24,39 +24,39 @@
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"name": "agent_working_dir",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"name": "setup_completed_at: DateTime<Utc>",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "archived!: bool",
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Integer"
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pinned!: bool",
|
||||
"name": "archived!: bool",
|
||||
"ordinal": 8,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"name": "pinned!: bool",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "worktree_deleted!: bool",
|
||||
"name": "name",
|
||||
"ordinal": 10,
|
||||
"type_info": "Bool"
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
@@ -68,13 +68,13 @@
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "f2dbb49b2f839e84a46fdd865d9982b758160517b93bc92d8e12060426daa05d"
|
||||
"hash": "9fb28e24e01689c959f8a039139407de7ee65535e6233f20a83250bd76ed3300"
|
||||
}
|
||||
44
crates/db/.sqlx/query-a25ebd2f707a19c565d61682bede36628e906b68ebc93bbf7f71d8bb57f72bfc.json
generated
Normal file
44
crates/db/.sqlx/query-a25ebd2f707a19c565d61682bede36628e906b68ebc93bbf7f71d8bb57f72bfc.json
generated
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "INSERT INTO sessions (id, workspace_id, executor)\n VALUES ($1, $2, $3)\n RETURNING id AS \"id!: Uuid\",\n workspace_id AS \"workspace_id!: Uuid\",\n executor,\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\"",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!: Uuid",
|
||||
"ordinal": 0,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id!: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "executor",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "a25ebd2f707a19c565d61682bede36628e906b68ebc93bbf7f71d8bb57f72bfc"
|
||||
}
|
||||
12
crates/db/.sqlx/query-a4a50fcfb903e6d0a315676f4f760e5bb7718e10ea550aedf990c9da84834416.json
generated
Normal file
12
crates/db/.sqlx/query-a4a50fcfb903e6d0a315676f4f760e5bb7718e10ea550aedf990c9da84834416.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "DELETE FROM migration_state",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a4a50fcfb903e6d0a315676f4f760e5bb7718e10ea550aedf990c9da84834416"
|
||||
}
|
||||
12
crates/db/.sqlx/query-a915c22f5ed0bb86c3a242ca38cbc1bfca40ebfe9096058c27e94479b67c7c02.json
generated
Normal file
12
crates/db/.sqlx/query-a915c22f5ed0bb86c3a242ca38cbc1bfca40ebfe9096058c27e94479b67c7c02.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE migration_state\n SET status = 'failed',\n error_message = $3,\n attempt_count = attempt_count + 1,\n updated_at = datetime('now', 'subsec')\n WHERE entity_type = $1 AND local_id = $2",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a915c22f5ed0bb86c3a242ca38cbc1bfca40ebfe9096058c27e94479b67c7c02"
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE sessions SET\n name = CASE WHEN $1 THEN $2 ELSE name END,\n updated_at = datetime('now', 'subsec')\n WHERE id = $3",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "abbda92ba42bea0f7d17d0945d51b011bf50e7b36ee50ed74988e053f6fb0eec"
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT\n id,\n workspace_id AS \"workspace_id: Uuid\",\n repo_id AS \"repo_id: Uuid\",\n pr_url,\n pr_number,\n pr_status AS \"pr_status: MergeStatus\",\n target_branch_name,\n merged_at AS \"merged_at: DateTime<Utc>\",\n merge_commit_sha,\n created_at AS \"created_at!: DateTime<Utc>\",\n updated_at AS \"updated_at!: DateTime<Utc>\",\n synced_at AS \"synced_at: DateTime<Utc>\"\n FROM pull_requests\n WHERE workspace_id = $1\n ORDER BY created_at DESC",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "workspace_id: Uuid",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "repo_id: Uuid",
|
||||
"ordinal": 2,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "pr_url",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "pr_number",
|
||||
"ordinal": 4,
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "pr_status: MergeStatus",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "target_branch_name",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merged_at: DateTime<Utc>",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "merge_commit_sha",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!: DateTime<Utc>",
|
||||
"ordinal": 9,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "updated_at!: DateTime<Utc>",
|
||||
"ordinal": 10,
|
||||
"type_info": "Datetime"
|
||||
},
|
||||
{
|
||||
"name": "synced_at: DateTime<Utc>",
|
||||
"ordinal": 11,
|
||||
"type_info": "Datetime"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "b21ce1663242be3d16c21a076d7b4b584692eb6ae19a3a5f19caba8ad16edce6"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user