fix(ui): keep dropdown triggers visible while open #1935
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Dev - Docker Images | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'frontend/apps/web/**' | |
| - 'frontend/apps/notify/**' | |
| - 'frontend/packages/**' | |
| - 'backend/**' | |
| - 'agents/**' | |
| - 'ops/**' | |
| - '.github/workflows/dev-docker-images.yml' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| AWS_REGION: us-east-1 | |
| jobs: | |
| # Build and validate deploy script (fail-fast before expensive builds) | |
| deploy-script: | |
| uses: ./.github/workflows/check-deploy-script.yml | |
| # Use the reusable parallel test workflow | |
| frontend-tests: | |
| uses: ./.github/workflows/test-frontend-parallel.yml | |
| agents-tests: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| task: [test, check, build] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: "1.3.10" | |
| - name: Cache Bun install | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.bun/install/cache | |
| key: agents-bun-${{ runner.os }}-${{ hashFiles('agents/bun.lock') }} | |
| restore-keys: | | |
| agents-bun-${{ runner.os }}- | |
| - name: Install dependencies | |
| working-directory: agents | |
| run: bun install --frozen-lockfile | |
| - name: Run ${{ matrix.task }} | |
| working-directory: agents | |
| run: | | |
| if [ "${{ matrix.task }}" = "test" ]; then | |
| bun test | |
| elif [ "${{ matrix.task }}" = "check" ]; then | |
| bun run check | |
| else | |
| bun run test:build | |
| fi | |
| backend-tests: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Cache GGUF model | |
| uses: actions/cache@v4 | |
| with: | |
| path: backend/llm/backends/llamacpp/models/*.gguf | |
| key: gguf-model-granite-v2 | |
| enableCrossOsArchive: true | |
| - name: Download GGUF model | |
| run: | | |
| if [ ! -f backend/llm/backends/llamacpp/models/granite-embedding-107m-multilingual-Q8_0.gguf ]; then | |
| mkdir -p backend/llm/backends/llamacpp/models | |
| curl -fSL -o backend/llm/backends/llamacpp/models/granite-embedding-107m-multilingual-Q8_0.gguf \ | |
| "https://huggingface.co/keisuke-miyako/granite-embedding-107m-multilingual-gguf-q8_0/resolve/main/granite-embedding-107m-multilingual-Q8_0.gguf?download=true" | |
| fi | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.26.2' | |
| - name: Install build dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake g++ libvulkan-dev glslc | |
| - name: Compute llama-go submodule sha | |
| id: llama-sha | |
| run: echo "sha=$(git -C backend/util/llama-go rev-parse HEAD)" >> "$GITHUB_OUTPUT" | |
| - name: Cache llama.cpp build (Vulkan) | |
| id: llama-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| backend/util/llama-go/libbinding.a | |
| backend/util/llama-go/libllama.a | |
| backend/util/llama-go/libggml*.a | |
| backend/util/llama-go/libcommon.a | |
| backend/util/llama-go/build | |
| # Cache key suffix `portable` indicates GGML_NATIVE=OFF builds. | |
| # Older `llama-vulkan-linux-<sha>` caches were built with | |
| # GGML_NATIVE=ON on heterogeneous ubuntu-latest runners, which | |
| # baked AVX-512 instructions into the artifact and crashed with | |
| # SIGILL on runners without AVX-512. | |
| key: llama-vulkan-linux-portable-${{ steps.llama-sha.outputs.sha }} | |
| - name: Build llama.cpp (with Vulkan GPU support) | |
| if: steps.llama-cache.outputs.cache-hit != 'true' | |
| run: | | |
| cd backend/util/llama-go | |
| BUILD_TYPE=vulkan CMAKE_ARGS="-DBUILD_SHARED_LIBS=OFF -DGGML_NATIVE=OFF" make libbinding.a | |
| - name: Run tests | |
| run: go test --count 1 ./backend/... | |
| env: | |
| CGO_ENABLED: 1 | |
| LIBRARY_PATH: ${{ github.workspace }}/backend/util/llama-go | |
| C_INCLUDE_PATH: ${{ github.workspace }}/backend/util/llama-go | |
| LLAMA_LOG: error | |
| # Run tests again with the race-detector. | |
| # Using the same job to reuse the build cache. | |
| - name: Run tests with race detector | |
| run: go test --count 1 -race ./backend/... | |
| env: | |
| CGO_ENABLED: 1 | |
| LIBRARY_PATH: ${{ github.workspace }}/backend/util/llama-go | |
| C_INCLUDE_PATH: ${{ github.workspace }}/backend/util/llama-go | |
| LLAMA_LOG: error | |
| # Build frontend apps and run performance tests. | |
| # Uploads pre-built artifacts so Docker jobs skip rebuilding. | |
| build-and-perf-test: | |
| runs-on: ubuntu-latest | |
| needs: [frontend-tests, backend-tests, deploy-script] | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Install Node.js 22 | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 22 | |
| cache: 'pnpm' | |
| - name: Install Dependencies | |
| run: pnpm install --frozen-lockfile --prefer-offline | |
| - name: Build Web App | |
| run: pnpm web:prod | |
| - name: Run Notify Tests | |
| run: pnpm --filter @shm/notify test | |
| - name: Build Notify App | |
| run: pnpm notify:build | |
| - name: Start Web Server | |
| run: | | |
| pnpm web:start & | |
| sleep 5 # Wait for server to start | |
| - name: Run Performance Tests | |
| run: | | |
| cd frontend/apps/perf-web | |
| pnpm start --url http://localhost:3000 --app web | |
| - name: Upload web build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: web-build | |
| path: frontend/apps/web/build/ | |
| retention-days: 1 | |
| - name: Upload notify build artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: notify-build | |
| path: frontend/apps/notify/build/ | |
| retention-days: 1 | |
| docker-web: | |
| runs-on: ubuntu-latest | |
| needs: [build-and-perf-test] | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Get commit date | |
| run: | | |
| COMMIT_DATE=$(git show -s --format="%cd" ${{ github.sha }}) | |
| echo "COMMIT_DATE=$COMMIT_DATE" >> $GITHUB_ENV | |
| - name: Download web build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: web-build | |
| path: frontend/apps/web/build/ | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: DockerHub Release seedhypermedia/web:dev | |
| uses: docker/build-push-action@v4 | |
| with: | |
| context: . | |
| push: true | |
| file: frontend/apps/web/Dockerfile | |
| tags: seedhypermedia/web:dev | |
| build-args: | | |
| PREBUILT=true | |
| SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} | |
| SITE_SENTRY_DSN=${{ secrets.SITE_SENTRY_DSN }} | |
| COMMIT_HASH=${{ github.sha }} | |
| BRANCH=${{ github.ref }} | |
| DATE=${{ env.COMMIT_DATE }} | |
| cache-from: type=gha,scope=docker-web-dev | |
| cache-to: type=gha,mode=max,scope=docker-web-dev | |
| docker-notify: | |
| runs-on: ubuntu-latest | |
| needs: [build-and-perf-test] | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Get commit date | |
| run: | | |
| COMMIT_DATE=$(git show -s --format="%cd" ${{ github.sha }}) | |
| echo "COMMIT_DATE=$COMMIT_DATE" >> $GITHUB_ENV | |
| - name: Download notify build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: notify-build | |
| path: frontend/apps/notify/build/ | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: DockerHub Release seedhypermedia/notify:dev | |
| uses: docker/build-push-action@v4 | |
| with: | |
| context: . | |
| push: true | |
| file: frontend/apps/notify/Dockerfile | |
| tags: seedhypermedia/notify:dev | |
| build-args: | | |
| PREBUILT=true | |
| SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} | |
| NOTIFY_SENTRY_DSN=${{ secrets.NOTIFY_SENTRY_DSN }} | |
| COMMIT_HASH=${{ github.sha }} | |
| BRANCH=${{ github.ref }} | |
| DATE=${{ env.COMMIT_DATE }} | |
| cache-from: type=gha,scope=docker-notify-dev | |
| cache-to: type=gha,mode=max,scope=docker-notify-dev | |
| docker-site: | |
| runs-on: ubuntu-latest | |
| needs: [frontend-tests, backend-tests] | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Get commit date | |
| run: | | |
| COMMIT_DATE=$(git show -s --format="%cd" ${{ github.sha }}) | |
| echo "COMMIT_DATE=$COMMIT_DATE" >> $GITHUB_ENV | |
| - name: Cache GGUF model | |
| uses: actions/cache@v4 | |
| with: | |
| path: backend/llm/backends/llamacpp/models/*.gguf | |
| key: gguf-model-granite-v2 | |
| enableCrossOsArchive: true | |
| - name: Download GGUF model | |
| run: | | |
| if [ ! -f backend/llm/backends/llamacpp/models/granite-embedding-107m-multilingual-Q8_0.gguf ]; then | |
| mkdir -p backend/llm/backends/llamacpp/models | |
| curl -fSL -o backend/llm/backends/llamacpp/models/granite-embedding-107m-multilingual-Q8_0.gguf \ | |
| "https://huggingface.co/keisuke-miyako/granite-embedding-107m-multilingual-gguf-q8_0/resolve/main/granite-embedding-107m-multilingual-Q8_0.gguf?download=true" | |
| fi | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: DockerHub Release seedhypermedia/site:dev | |
| uses: docker/build-push-action@v4 | |
| with: | |
| context: . | |
| push: true | |
| file: backend/cmd/seed-daemon/Dockerfile | |
| tags: seedhypermedia/site:dev | |
| build-args: | | |
| COMMIT_HASH=${{ github.sha }} | |
| BRANCH=${{ github.ref }} | |
| DATE=${{ env.COMMIT_DATE }} | |
| cache-from: type=gha,scope=docker-site-dev | |
| cache-to: type=gha,mode=max,scope=docker-site-dev | |
| docker-monitord: | |
| runs-on: ubuntu-latest | |
| needs: [frontend-tests, backend-tests] | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: DockerHub Release seedhypermedia/monitord:dev | |
| uses: docker/build-push-action@v4 | |
| with: | |
| push: true | |
| file: backend/cmd/monitord/Dockerfile | |
| tags: seedhypermedia/monitord:dev | |
| cache-from: type=gha,scope=docker-monitord-dev | |
| cache-to: type=gha,mode=max,scope=docker-monitord-dev | |
| docker-relayd: | |
| runs-on: ubuntu-latest | |
| needs: [frontend-tests, backend-tests] | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: DockerHub Release seedhypermedia/relayd:dev | |
| uses: docker/build-push-action@v4 | |
| with: | |
| push: true | |
| file: backend/cmd/relayd/Dockerfile | |
| tags: seedhypermedia/relayd:dev | |
| cache-from: type=gha,scope=docker-relayd-dev | |
| cache-to: type=gha,mode=max,scope=docker-relayd-dev | |
| docker-agents: | |
| runs-on: ubuntu-latest | |
| needs: [agents-tests] | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v2 | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v2 | |
| with: | |
| username: ${{ secrets.DOCKERHUB_USERNAME }} | |
| password: ${{ secrets.DOCKERHUB_TOKEN }} | |
| - name: DockerHub Release seedhypermedia/agents:dev | |
| uses: docker/build-push-action@v4 | |
| with: | |
| context: . | |
| push: true | |
| file: agents/Dockerfile | |
| tags: seedhypermedia/agents:dev | |
| cache-from: type=gha,scope=docker-agents-dev | |
| cache-to: type=gha,mode=max,scope=docker-agents-dev | |
| # Upload deploy script to S3 alongside dev docker images | |
| publish-deploy-script: | |
| runs-on: ubuntu-latest | |
| needs: [deploy-script] | |
| if: ${{ github.ref == 'refs/heads/main' }} | |
| steps: | |
| - name: Download deploy-script artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: deploy-script | |
| path: deploy-script | |
| - name: Upload deploy.js to S3 | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_KEY }} | |
| AWS_DEFAULT_REGION: eu-west-2 | |
| run: | | |
| aws s3 cp deploy-script/deploy.js s3://seedappdev/dev/latest/deploy.js | |