From 349d75cc280433ba758fb04259bb3d9c5bf3ea17 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Nov 2025 23:06:37 +0000 Subject: [PATCH 1/5] Initial plan From 74452a4d685eecdac4d22b8d9238fa1b5d717060 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 17 Nov 2025 23:15:28 +0000 Subject: [PATCH 2/5] Fix: Preserve null value for expire parameter in ExpirationInput - Fixed reactive block in expirationInput.svelte to check for null before converting to ISO date - When "Never" is selected, value now remains null instead of being converted to '1970-01-01' - This allows the API to correctly handle null expiration dates for API keys and file tokens Co-authored-by: stnguyen90 <1477010+stnguyen90@users.noreply.github.com> --- src/lib/components/expirationInput.svelte | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/components/expirationInput.svelte b/src/lib/components/expirationInput.svelte index eff95ba7d8..9782dfae5d 100644 --- a/src/lib/components/expirationInput.svelte +++ b/src/lib/components/expirationInput.svelte @@ -134,7 +134,10 @@ value = expirationSelect === 'custom' ? expirationCustom : expirationSelect; } - value = toLocaleDateISO(new Date(value).getTime()); + // Only convert to ISO date if value is not null + if (value !== null) { + value = toLocaleDateISO(new Date(value).getTime()); + } } $: helper = From c772abc2e3cb466de6f4ce917beaa1bf9953ac4c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 02:56:12 +0000 Subject: [PATCH 3/5] Fix: Handle empty string initialization for API key expire parameter - Updated initialization logic to handle both null and invalid date values (including empty strings) - Removed the check for expirationSelect !== null to allow proper initialization when "Never" is selected - Added isValidDate check before ISO date conversion to prevent converting invalid dates to 'n/a' - This fixes the issue where API keys couldn't be created with "Never" expiration when the parent component initializes expire as an empty string Co-authored-by: stnguyen90 <1477010+stnguyen90@users.noreply.github.com> --- src/lib/components/expirationInput.svelte | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/components/expirationInput.svelte b/src/lib/components/expirationInput.svelte index 9782dfae5d..34c5332f30 100644 --- a/src/lib/components/expirationInput.svelte +++ b/src/lib/components/expirationInput.svelte @@ -123,8 +123,8 @@ let hasUserInteracted = false; $: { - // Set initial value if value is null on first load - if (!initialized && value === null && expirationSelect !== null) { + // Set initial value if value is null or invalid on first load + if (!initialized && (value === null || !isValidDate(value))) { value = expirationSelect === 'custom' ? expirationCustom : expirationSelect; initialized = true; } @@ -134,8 +134,8 @@ value = expirationSelect === 'custom' ? expirationCustom : expirationSelect; } - // Only convert to ISO date if value is not null - if (value !== null) { + // Only convert to ISO date if value is not null and is a valid date + if (value !== null && isValidDate(value)) { value = toLocaleDateISO(new Date(value).getTime()); } } From a17bb097a69791cd1860755253f23e21a3d30190 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 18 Nov 2025 04:25:56 +0000 Subject: [PATCH 4/5] docs: Add mandatory pre-completion checklist to AGENTS.md Added a "Required Pre-Completion Checklist" section that instructs agents to: - Always run format, check, lint, test, and build before finishing - Fix any failures before marking work complete - Never skip these mandatory quality gates This addresses the requirement to ensure all code changes are properly validated. Co-authored-by: stnguyen90 <1477010+stnguyen90@users.noreply.github.com> --- .github/workflows/dockerize-profiles.yml | 84 ++++++++++++------------ AGENTS.md | 19 ++++++ 2 files changed, 61 insertions(+), 42 deletions(-) diff --git a/.github/workflows/dockerize-profiles.yml b/.github/workflows/dockerize-profiles.yml index 8e09a234a4..aafa95f324 100644 --- a/.github/workflows/dockerize-profiles.yml +++ b/.github/workflows/dockerize-profiles.yml @@ -1,49 +1,49 @@ name: Dockerize Profiles on: - push: - branches: [feat-profiles] - pull_request: - types: [opened, synchronize, reopened] - branches: [feat-profiles] - workflow_dispatch: + push: + branches: [feat-profiles] + pull_request: + types: [opened, synchronize, reopened] + branches: [feat-profiles] + workflow_dispatch: jobs: - dockerize-profiles: - runs-on: ubuntu-latest - - steps: - - name: Checkout the repo - uses: actions/checkout@v2 - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ vars.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + dockerize-profiles: + runs-on: ubuntu-latest - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@v5 - with: - images: appwrite/console-profiles - tags: | - type=ref,event=branch,prefix=branch- - type=ref,event=pr - type=sha,prefix=sha- - type=raw,value=gh-${{ github.run_id}} - flavor: | - latest=false + steps: + - name: Checkout the repo + uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ vars.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build and push Docker image - id: push - uses: docker/build-push-action@v6 - with: - context: . - push: true - platforms: linux/amd64,linux/arm64 - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: appwrite/console-profiles + tags: | + type=ref,event=branch,prefix=branch- + type=ref,event=pr + type=sha,prefix=sha- + type=raw,value=gh-${{ github.run_id}} + flavor: | + latest=false + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@v6 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/AGENTS.md b/AGENTS.md index 82bcb13c7f..38c3f89e31 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -101,4 +101,23 @@ src/ 5. Before commit: `pnpm run check && pnpm run format && pnpm run lint && pnpm run test && pnpm run build` 6. **Take screenshots**: For any UI changes, capture screenshots and include them in the PR description or comments before finalizing +## Required Pre-Completion Checklist + +**CRITICAL**: Before finishing any work or marking a task complete, agents MUST run the following commands in order and ensure all pass: + +1. **`pnpm run format`** - Auto-fix all formatting issues +2. **`pnpm run check`** - Verify TypeScript/Svelte types (must show 0 errors, 0 warnings) +3. **`pnpm run lint`** - Check code style (ignore pre-existing issues in files you didn't modify) +4. **`pnpm run test`** - Run all unit tests (all tests must pass) +5. **`pnpm run build`** - Ensure production build succeeds + +If any command fails: + +- **Format/Lint**: Run `pnpm run format` to auto-fix, then re-check +- **Type errors**: Fix all TypeScript errors in files you modified +- **Test failures**: Fix failing tests or ensure failures are unrelated to your changes +- **Build failures**: Debug and resolve build issues before proceeding + +**Never skip these checks** - they are mandatory quality gates before any work is considered complete. + **Trust these instructions** - only search if incomplete/incorrect. See CONTRIBUTING.md for PR conventions. Use `--frozen-lockfile` always. Docker builds: multi-stage, final image is nginx serving static files from `/console` path. From 0d77f88d4ae7243310dd04ee42d9f2aba58ca785 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 20 Nov 2025 17:49:44 +0000 Subject: [PATCH 5/5] Simplify fix: Initialize expire as null in API key creation - Changed API key create component to initialize `expire = null` instead of `expire = ''` - Reverted complex invalid date handling in ExpirationInput component - Kept only the essential null value handling in ExpirationInput - This matches the approach used in file token component and is simpler This addresses reviewer feedback to handle the issue at the source (parent component) rather than making the ExpirationInput component more complex. Co-authored-by: stnguyen90 <1477010+stnguyen90@users.noreply.github.com> --- src/lib/components/expirationInput.svelte | 8 ++++---- .../overview/(components)/create.svelte | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/components/expirationInput.svelte b/src/lib/components/expirationInput.svelte index 34c5332f30..9782dfae5d 100644 --- a/src/lib/components/expirationInput.svelte +++ b/src/lib/components/expirationInput.svelte @@ -123,8 +123,8 @@ let hasUserInteracted = false; $: { - // Set initial value if value is null or invalid on first load - if (!initialized && (value === null || !isValidDate(value))) { + // Set initial value if value is null on first load + if (!initialized && value === null && expirationSelect !== null) { value = expirationSelect === 'custom' ? expirationCustom : expirationSelect; initialized = true; } @@ -134,8 +134,8 @@ value = expirationSelect === 'custom' ? expirationCustom : expirationSelect; } - // Only convert to ISO date if value is not null and is a valid date - if (value !== null && isValidDate(value)) { + // Only convert to ISO date if value is not null + if (value !== null) { value = toLocaleDateISO(new Date(value).getTime()); } } diff --git a/src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte b/src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte index 84e6a78095..4c9bb81508 100644 --- a/src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte +++ b/src/routes/(console)/project-[region]-[project]/overview/(components)/create.svelte @@ -24,8 +24,8 @@ let isSubmitting = writable(false); let scopes: string[] = []; - let name = '', - expire = ''; + let name = ''; + let expire: string | null = null; async function create() { try {