diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index ab2397e..27acecc 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -86,82 +86,4 @@ jobs: - name: Test run: npm run test working-directory: frontend - - docker-backend: - name: Build and Push Backend Image - runs-on: docker - needs: [check-backend] - if: github.ref == 'refs/heads/main' - steps: - - name: Checkout Repo - uses: https://github.com/actions/checkout@v4 - - - name: Set up Docker Buildx - uses: https://github.com/docker/setup-buildx-action@v3 - - - name: Login to Forgejo Container Registry - uses: https://github.com/docker/login-action@v3 - with: - registry: ${{ gitea.server_url }} - username: ${{ gitea.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: https://github.com/docker/metadata-action@v5 - with: - images: ${{ gitea.server_url }}/${{ gitea.repository }}/backend - tags: | - type=ref,event=branch - type=sha,prefix={{branch}}- - type=raw,value=latest,enable={{is_default_branch}} - - - name: Build and push image - uses: https://github.com/docker/build-push-action@v5 - with: - context: ./backend - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max - - docker-frontend: - name: Build and Push Frontend Image - runs-on: docker - needs: [check-frontend] - if: github.ref == 'refs/heads/main' - steps: - - name: Checkout Repo - uses: https://github.com/actions/checkout@v4 - - - name: Set up Docker Buildx - uses: https://github.com/docker/setup-buildx-action@v3 - - - name: Login to Forgejo Container Registry - uses: https://github.com/docker/login-action@v3 - with: - registry: ${{ gitea.server_url }} - username: ${{ gitea.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: https://github.com/docker/metadata-action@v5 - with: - images: ${{ gitea.server_url }}/${{ gitea.repository }}/frontend - tags: | - type=ref,event=branch - type=sha,prefix={{branch}}- - type=raw,value=latest,enable={{is_default_branch}} - - - name: Build and push image - uses: https://github.com/docker/build-push-action@v5 - with: - context: ./frontend - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/.forgejo/workflows/docker.yml b/.forgejo/workflows/docker.yml new file mode 100644 index 0000000..a69ac85 --- /dev/null +++ b/.forgejo/workflows/docker.yml @@ -0,0 +1,86 @@ +name: Docker Build + +on: + push: + branches: [ main ] + +env: + # Should speed up builds. + CARGO_INCREMENTAL: 0 + # Should reduce the size of ./target to improve cache load/store. + CARGO_PROFILE_TEST_DEBUG: 0 + +jobs: + docker-backend: + name: Build and Push Backend Image + runs-on: docker + steps: + - name: Checkout Repo + uses: https://github.com/actions/checkout@v4 + + - name: Set up Docker Buildx + uses: https://github.com/docker/setup-buildx-action@v3 + + - name: Login to Forgejo Container Registry + uses: https://github.com/docker/login-action@v3 + with: + registry: ${{ gitea.server_url }} + username: ${{ gitea.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: https://github.com/docker/metadata-action@v5 + with: + images: ${{ gitea.server_url }}/${{ gitea.repository }}/backend + tags: | + type=ref,event=branch + type=sha,prefix={{branch}}- + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push image + uses: https://github.com/docker/build-push-action@v5 + with: + context: ./backend + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + docker-frontend: + name: Build and Push Frontend Image + runs-on: docker + steps: + - name: Checkout Repo + uses: https://github.com/actions/checkout@v4 + + - name: Set up Docker Buildx + uses: https://github.com/docker/setup-buildx-action@v3 + + - name: Login to Forgejo Container Registry + uses: https://github.com/docker/login-action@v3 + with: + registry: ${{ gitea.server_url }} + username: ${{ gitea.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: https://github.com/docker/metadata-action@v5 + with: + images: ${{ gitea.server_url }}/${{ gitea.repository }}/frontend + tags: | + type=ref,event=branch + type=sha,prefix={{branch}}- + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push image + uses: https://github.com/docker/build-push-action@v5 + with: + context: ./frontend + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 8a21554..207f7de 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -289,6 +289,7 @@ dependencies = [ "serde", "sqlx", "tokio", + "tower-http", "tracing", "tracing-subscriber", "uuid", @@ -3490,6 +3491,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags 2.9.3", + "bytes", + "http 1.3.1", + "pin-project-lite", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" diff --git a/backend/src/main.rs b/backend/src/main.rs index 9e47334..635d45d 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,5 +1,5 @@ use axum::{Router, routing::get}; -use tower_http::cors::{CorsLayer, Any}; +use tower_http::cors::{Any, CorsLayer}; mod database; mod models; @@ -17,8 +17,12 @@ async fn main() { let cors = if std::env::var("RUST_ENV").unwrap_or_default() == "production" { CorsLayer::new() .allow_origin([ - "https://tiramisu.one".parse::().unwrap(), - "https://*.tiramisu.one".parse::().unwrap() + "https://tiramisu.one" + .parse::() + .unwrap(), + "https://*.tiramisu.one" + .parse::() + .unwrap(), ]) .allow_methods(Any) .allow_headers(Any) diff --git a/frontend/app/services/api.test.ts b/frontend/app/services/api.test.ts index 3853bc1..1eee218 100644 --- a/frontend/app/services/api.test.ts +++ b/frontend/app/services/api.test.ts @@ -52,9 +52,12 @@ describe('API Client', () => { const result = await apiClient.listTasks() - expect(mockFetch).toHaveBeenCalledWith('/api/tasks', { - headers: { 'Content-Type': 'application/json' }, - }) + expect(mockFetch).toHaveBeenCalledWith( + 'http://localhost:3000/api/tasks', + { + headers: { 'Content-Type': 'application/json' }, + } + ) expect(result).toEqual(mockTasks) }) @@ -94,9 +97,12 @@ describe('API Client', () => { const result = await apiClient.getTask(mockTask.id) - expect(mockFetch).toHaveBeenCalledWith(`/api/tasks/${mockTask.id}`, { - headers: { 'Content-Type': 'application/json' }, - }) + expect(mockFetch).toHaveBeenCalledWith( + `http://localhost:3000/api/tasks/${mockTask.id}`, + { + headers: { 'Content-Type': 'application/json' }, + } + ) expect(result).toEqual(mockTask) }) @@ -130,11 +136,14 @@ describe('API Client', () => { const result = await apiClient.createTask(newTaskData) - expect(mockFetch).toHaveBeenCalledWith('/api/tasks', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(newTaskData), - }) + expect(mockFetch).toHaveBeenCalledWith( + 'http://localhost:3000/api/tasks', + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(newTaskData), + } + ) expect(result).toEqual(mockTask) }) @@ -174,11 +183,14 @@ describe('API Client', () => { const result = await apiClient.updateTask(mockTask.id, updateData) - expect(mockFetch).toHaveBeenCalledWith(`/api/tasks/${mockTask.id}`, { - method: 'PUT', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(updateData), - }) + expect(mockFetch).toHaveBeenCalledWith( + `http://localhost:3000/api/tasks/${mockTask.id}`, + { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(updateData), + } + ) expect(result).toEqual(updatedTask) }) @@ -211,10 +223,13 @@ describe('API Client', () => { const result = await apiClient.deleteTask(mockTask.id) expect(result).toBeNull() - expect(mockFetch).toHaveBeenCalledWith(`/api/tasks/${mockTask.id}`, { - method: 'DELETE', - headers: { 'Content-Type': 'application/json' }, - }) + expect(mockFetch).toHaveBeenCalledWith( + `http://localhost:3000/api/tasks/${mockTask.id}`, + { + method: 'DELETE', + headers: { 'Content-Type': 'application/json' }, + } + ) }) it('should handle delete errors', async () => {