diff --git a/docker/compose.dev.yaml b/.devcontainer/compose.yaml similarity index 81% rename from docker/compose.dev.yaml rename to .devcontainer/compose.yaml index 3b9722f..f2c5ac6 100644 --- a/docker/compose.dev.yaml +++ b/.devcontainer/compose.yaml @@ -1,18 +1,15 @@ name: pgbackweb-dev services: - app: - container_name: pbw_app + devcontainer: + container_name: pbw_devcontainer build: context: ../ dockerfile: ./docker/Dockerfile.dev ports: - "8085:8085" volumes: - - ../:/app - - pbw_vol_app_ssh:/root/.ssh - - pbw_vol_app_gh:/root/.config/gh - - pbw_vol_app_go_mod_cache:/root/go/pkg/mod + - ../..:/workspaces:cached networks: - pbw_network depends_on: @@ -53,7 +50,7 @@ services: - "9090:9090" environment: MINIO_ROOT_USER: "root" - MINIO_ROOT_PASSWORD: "password" + MINIO_ROOT_PASSWORD: "root" volumes: - pbw_vol_minio:/data command: minio server /data/minio --console-address ":9090" @@ -61,9 +58,6 @@ services: - pbw_network volumes: - pbw_vol_app_ssh: - pbw_vol_app_gh: - pbw_vol_app_go_mod_cache: pbw_vol_postgres: pbw_vol_minio: diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..bd89559 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,85 @@ +{ + "dockerComposeFile": "./compose.yaml", + "service": "devcontainer", + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", + "customizations": { + "vscode": { + "extensions": [ + "golang.go", + "bradlc.vscode-tailwindcss", + "standard.vscode-standard", + "denoland.vscode-deno", + "mhutchie.git-graph", + "mutantdino.resourcemonitor", + "Compile-TomaszKasperczyk.copy-to-llm" + ], + "settings": { + ///// + // Editor settings + ///// + "editor.formatOnSave": true, + "editor.foldingStrategy": "indentation", + "editor.rulers": [ + 80 + ], + "files.eol": "\n", + ///// + // Language specific settings + ///// + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features" + }, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features" + }, + // JavaScript & Standard + "standard.enable": true, + "standard.autoFixOnSave": true, + "[typescript]": { + "editor.defaultFormatter": "denoland.vscode-deno" + }, + "[javascript]": { + "editor.defaultFormatter": "standard.vscode-standard" + }, + "[css]": { + "editor.defaultFormatter": "vscode.css-language-features" + }, + "[html]": { + "editor.defaultFormatter": "vscode.html-language-features" + }, + "[markdown]": { + "editor.defaultFormatter": "vscode.markdown-language-features" + }, + // Go & Golangci-lint + "[go]": { + "editor.defaultFormatter": "golang.go" + }, + "go.lintTool": "golangci-lint", + "go.lintFlags": [ + "--fast" + ], + // Deno + "deno.enable": true, + "deno.enablePaths": [ + "./scripts" + ], + ///// + // Tailwind CSS + NodX + ///// + "tailwindCSS.includeLanguages": { + "go": "go" + }, + "tailwindCSS.experimental.classRegex": [ + [ + "Class\\(([^)]*)\\)", + "[\"`]([^\"`]*)[\"`]" + ], // Class("...") or Class(`...`) + [ + "ClassMap\\{([^)]*)\\}", + "[\"`]([^\"`]*)[\"`]" + ] // ClassMap{"..."} or ClassMap{`...`} + ] + } + } + } +} \ No newline at end of file diff --git a/.env.dev b/.env.dev index 37d7ced..c639858 100644 --- a/.env.dev +++ b/.env.dev @@ -11,4 +11,4 @@ PBW_ENCRYPTION_KEY="encryption-key" # Database connection string for a PostgreSQL database where the pgbackweb # will store its data. -PBW_POSTGRES_CONN_STRING="postgresql://postgres:password@host.docker.internal:5432/pgbackweb?sslmode=disable" +PBW_POSTGRES_CONN_STRING="postgresql://postgres:password@pbw_postgres:5432/pgbackweb?sslmode=disable" diff --git a/.github/workflows/lint-test-build.yaml b/.github/workflows/lint-test-build.yaml index 3b429f1..b1f53f1 100644 --- a/.github/workflows/lint-test-build.yaml +++ b/.github/workflows/lint-test-build.yaml @@ -1,6 +1,6 @@ -name: Lint, test & build - +name: Lint, test, and build on: + workflow_dispatch: push: branches: - main @@ -11,40 +11,44 @@ on: - develop jobs: - build-test-lint: - name: Build, test & lint - runs-on: ubuntu-latest + lint-test-build: strategy: matrix: - platform: [linux/amd64, linux/arm64] + vars: [ + {os: ubuntu-24.04, platform: linux/amd64}, + {os: ubuntu-24.04-arm, platform: linux/arm64} + ] + + name: Lint, test, and build the code + runs-on: ${{ matrix.vars.os }} + timeout-minutes: 20 + steps: - - name: Checkout code + - name: Checkout uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx + - name: Setup Docker buildx for multi-architecture builds uses: docker/setup-buildx-action@v3 + with: + use: true - - name: Build Docker image - run: | - docker buildx create --use - docker buildx build \ - --platform ${{ matrix.platform }} \ - --build-arg TARGETPLATFORM=${{ matrix.platform }} \ - -t pbw-test-${{ matrix.platform }}:latest \ - -f ./docker/Dockerfile.cicd \ - --load . + - name: Build the Docker image + run: > + docker buildx build + --load + --platform ${{ matrix.vars.platform }} + --tag pgbackweb:latest + --file docker/Dockerfile.dev . - - name: Run dependencies check - run: docker run --rm --platform ${{ matrix.platform }} pbw-test-${{ matrix.platform }}:latest task check-deps - - - name: Run linter - run: docker run --rm --platform ${{ matrix.platform }} pbw-test-${{ matrix.platform }}:latest task lint-only - - - name: Run tests - run: docker run --rm --platform ${{ matrix.platform }} pbw-test-${{ matrix.platform }}:latest task test-only - - - name: Build project - run: docker run --rm --platform ${{ matrix.platform }} pbw-test-${{ matrix.platform }}:latest task build + - name: Run lint, test, and build + run: > + docker run --rm -v $PWD:/app pgbackweb:latest /bin/bash -c " + cd /app && + npm install && + go mod download && + task fixperms && + task check-deps && + task lint-only && + task test-only && + task build + " diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 99b3852..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "recommendations": [ - "golang.go", - "bradlc.vscode-tailwindcss", - "standard.vscode-standard" - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 2db35ef..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - ///// - // Editor settings - ///// - "editor.formatOnSave": true, - "editor.foldingStrategy": "indentation", - "editor.rulers": [ - 80 - ], - "files.eol": "\n", - ///// - // Language specific settings - ///// - "[json]": { - "editor.defaultFormatter": "vscode.json-language-features" - }, - "[jsonc]": { - "editor.defaultFormatter": "vscode.json-language-features" - }, - // JavaScript & Standard - "standard.enable": true, - "standard.autoFixOnSave": true, - "[javascript]": { - "editor.defaultFormatter": "standard.vscode-standard" - }, - "[css]": { - "editor.defaultFormatter": "vscode.css-language-features" - }, - "[html]": { - "editor.defaultFormatter": "vscode.html-language-features" - }, - "[markdown]": { - "editor.defaultFormatter": "vscode.markdown-language-features" - }, - "[go]": { - "editor.defaultFormatter": "golang.go" - }, - ///// - // Tailwind CSS + Gomponents - // https://gist.github.com/eduardolat/438a1de077ccac6b9792153e708c1824 - ///// - "tailwindCSS.includeLanguages": { - "go": "go", - }, - "tailwindCSS.experimental.classRegex": [ - [ - "Class\\(([^)]*)\\)", - "[\"`]([^\"`]*)[\"`]" - ], // Class("...") or Class(`...`) - [ - "Classes\\(([^)]*)\\)", - "[\"`]([^\"`]*)[\"`]" - ], // Classes("...") or Classes(`...`) - [ - "Class\\{([^)]*)\\}", - "[\"`]([^\"`]*)[\"`]" - ], // Class{"..."} or Class{`...`} - [ - "Classes\\{([^)]*)\\}", - "[\"`]([^\"`]*)[\"`]" - ], // Classes{"..."} or Classes{`...`} - [ - "Class:\\s*[\"`]([^\"`]*)[\"`]" - ], // Class: "..." or Class: `...` - [ - "Classes:\\s*[\"`]([^\"`]*)[\"`]" - ], // Classes: "..." or Classes: `...` - ] -} \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index 3065e0c..1728c7b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,6 +1,3 @@ -# Declare the target platform to support multi-arch builds -ARG TARGETPLATFORM - # To make sure we have the node, and golang binaries FROM node:20.17.0-bookworm AS node FROM golang:1.23.1-bookworm AS golang @@ -8,14 +5,20 @@ FROM golang:1.23.1-bookworm AS golang # Set the base image FROM debian:12.7 -# Re-declare ARG after FROM to make it available in this build stage +# Declare ARG to make it available in the RUN commands ARG TARGETPLATFORM RUN echo "Building for ${TARGETPLATFORM}" +RUN if [ "${TARGETPLATFORM}" != "linux/amd64" ] && [ "${TARGETPLATFORM}" != "linux/arm64" ]; then \ + echo "Unsupported architecture: ${TARGETPLATFORM}" && \ + exit 1; \ + fi # Set the general environment variables, and move to temp dir ENV DEBIAN_FRONTEND="noninteractive" +ENV PATH="$PATH:/usr/local/go/bin" +ENV PATH="$PATH:/usr/local/go-bin" +ENV PATH="$PATH:/usr/local/dl-bin" ENV GOBIN="/usr/local/go-bin" -ENV PATH="$PATH:/usr/local/go-bin:/usr/local/dl-bin:/usr/local/go/bin" RUN mkdir -p /app/temp /usr/local/go-bin /usr/local/dl-bin WORKDIR /app/temp @@ -79,6 +82,10 @@ RUN set -e && \ # Make binaries executable chmod +x /usr/local/dl-bin/* +# Default git config +# https://github.com/golangci/golangci-lint/issues/4033 +RUN git config --global --add safe.directory '*' + # Go to the app dir, delete the temporary dir and create backups dir WORKDIR /app RUN rm -rf /app/temp && \ diff --git a/docker/Dockerfile.cicd b/docker/Dockerfile.cicd deleted file mode 100644 index a4ff18a..0000000 --- a/docker/Dockerfile.cicd +++ /dev/null @@ -1,105 +0,0 @@ -# Declare the target platform to support multi-arch builds -ARG TARGETPLATFORM - -# To make sure we have the node, and golang binaries -FROM node:20.17.0-bookworm AS node -FROM golang:1.23.1-bookworm AS golang - -# Set the base image -FROM debian:12.7 - -# Re-declare ARG after FROM to make it available in this build stage -ARG TARGETPLATFORM -RUN echo "Building for ${TARGETPLATFORM}" - -# Set the general environment variables, and move to temp dir -ENV DEBIAN_FRONTEND="noninteractive" -ENV GOBIN="/usr/local/go-bin" -ENV PATH="$PATH:/usr/local/go-bin:/usr/local/dl-bin:/usr/local/go/bin" -RUN mkdir -p /app/temp /usr/local/go-bin /usr/local/dl-bin -WORKDIR /app/temp - -# Copy node binaries -COPY --from=node /usr/local/bin/ /usr/local/bin/ -COPY --from=node /usr/local/include/ /usr/local/include/ -COPY --from=node /usr/local/lib/ /usr/local/lib/ -COPY --from=node /usr/local/share/ /usr/local/share/ - -# Copy the golang binaries -COPY --from=golang /usr/local/go /usr/local/go - -# Add PostgreSQL repository and install system dependencies -# https://www.postgresql.org/download/linux/debian/ -RUN apt update && apt install -y postgresql-common && \ - /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && \ - apt update && apt install -y \ - wget unzip tzdata git \ - postgresql-client-13 postgresql-client-14 \ - postgresql-client-15 postgresql-client-16 \ - postgresql-client-17 && \ - rm -rf /var/lib/apt/lists/* - -# Install downloadable binaries -RUN set -e && \ - if [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \ - echo "Downloading arm64 binaries" && \ - # Install task - wget --no-verbose https://github.com/go-task/task/releases/download/v3.38.0/task_linux_arm64.tar.gz && \ - tar -xzf task_linux_arm64.tar.gz && \ - mv ./task /usr/local/dl-bin/task && \ - # Install goose - wget --no-verbose https://github.com/pressly/goose/releases/download/v3.22.0/goose_linux_arm64 && \ - mv ./goose_linux_arm64 /usr/local/dl-bin/goose && \ - # Install sqlc - wget --no-verbose https://github.com/sqlc-dev/sqlc/releases/download/v1.27.0/sqlc_1.27.0_linux_arm64.tar.gz && \ - tar -xzf sqlc_1.27.0_linux_arm64.tar.gz && \ - mv ./sqlc /usr/local/dl-bin/sqlc && \ - # Install golangci-lint - wget --no-verbose https://github.com/golangci/golangci-lint/releases/download/v1.60.3/golangci-lint-1.60.3-linux-arm64.tar.gz && \ - tar -xzf golangci-lint-1.60.3-linux-arm64.tar.gz && \ - mv ./golangci-lint-1.60.3-linux-arm64/golangci-lint /usr/local/dl-bin/golangci-lint; \ - else \ - echo "Downloading amd64 binaries" && \ - # Install task - wget --no-verbose https://github.com/go-task/task/releases/download/v3.38.0/task_linux_amd64.tar.gz && \ - tar -xzf task_linux_amd64.tar.gz && \ - mv ./task /usr/local/dl-bin/task && \ - # Install goose - wget --no-verbose https://github.com/pressly/goose/releases/download/v3.22.0/goose_linux_x86_64 && \ - mv ./goose_linux_x86_64 /usr/local/dl-bin/goose && \ - # Install sqlc - wget --no-verbose https://github.com/sqlc-dev/sqlc/releases/download/v1.27.0/sqlc_1.27.0_linux_amd64.tar.gz && \ - tar -xzf sqlc_1.27.0_linux_amd64.tar.gz && \ - mv ./sqlc /usr/local/dl-bin/sqlc && \ - # Install golangci-lint - wget --no-verbose https://github.com/golangci/golangci-lint/releases/download/v1.60.3/golangci-lint-1.60.3-linux-amd64.tar.gz && \ - tar -xzf golangci-lint-1.60.3-linux-amd64.tar.gz && \ - mv ./golangci-lint-1.60.3-linux-amd64/golangci-lint /usr/local/dl-bin/golangci-lint; \ - fi && \ - # Make binaries executable - chmod +x /usr/local/dl-bin/* - -# Go to the app dir, delete the temporary dir and create backups dir -WORKDIR /app -RUN rm -rf /app/temp && \ - mkdir /backups && \ - chmod 777 /backups - -############## -# START HERE # -############## - -# Copy and install nodejs dependencies -COPY package.json . -RUN npm install - -# Copy and install go dependencies -COPY go.mod . -COPY go.sum . -RUN go mod download - -# Copy the rest of the files -COPY . . - -# Fix permissions if needed -RUN task fixperms diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index f3d1881..ea08e62 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -1,6 +1,3 @@ -# Declare the target platform to support multi-arch builds -ARG TARGETPLATFORM - # To make sure we have the node, and golang binaries FROM node:20.17.0-bookworm AS node FROM golang:1.23.1-bookworm AS golang @@ -8,14 +5,20 @@ FROM golang:1.23.1-bookworm AS golang # Set the base image FROM debian:12.7 -# Re-declare ARG after FROM to make it available in this build stage +# Declare ARG to make it available in the RUN commands ARG TARGETPLATFORM RUN echo "Building for ${TARGETPLATFORM}" +RUN if [ "${TARGETPLATFORM}" != "linux/amd64" ] && [ "${TARGETPLATFORM}" != "linux/arm64" ]; then \ + echo "Unsupported architecture: ${TARGETPLATFORM}" && \ + exit 1; \ + fi # Set the general environment variables, and move to temp dir ENV DEBIAN_FRONTEND="noninteractive" +ENV PATH="$PATH:/usr/local/go/bin" +ENV PATH="$PATH:/usr/local/go-bin" +ENV PATH="$PATH:/usr/local/dl-bin" ENV GOBIN="/usr/local/go-bin" -ENV PATH="$PATH:/usr/local/go-bin:/usr/local/dl-bin:/usr/local/go/bin" RUN mkdir -p /app/temp /usr/local/go-bin /usr/local/dl-bin WORKDIR /app/temp @@ -79,6 +82,10 @@ RUN set -e && \ # Make binaries executable chmod +x /usr/local/dl-bin/* +# Default git config +# https://github.com/golangci/golangci-lint/issues/4033 +RUN git config --global --add safe.directory '*' + # Go to the app dir, delete the temporary dir and create backups dir WORKDIR /app RUN rm -rf /app/temp && \ @@ -95,4 +102,4 @@ RUN echo "\n\n" >> /root/.bashrc && \ cat /usr/local/bin/startup.sh >> /root/.bashrc # Command just to keep the container running -CMD ["tail", "-f", "/dev/null"] +CMD ["sleep", "infinity"] diff --git a/docker/README.md b/docker/README.md index b8f51b6..d2b289b 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,25 +1,9 @@ # Docker -This folder is responsible for storing all Dockerfiles for the different Docker images required for the project. IT IS IMPERATIVE that all images have the same dependencies and versions to ensure consistency and reproducibility across different environments. - -To make sure they are identical, please always ensure that all instructions in the Dockerfiles are exactly the same up to the following comment: - -```Dockerfile -############## -# START HERE # -############## -``` - -After the above comment, you can add the necessary instructions for the specific image. Please replicate all dependencies and environment-related instructions in all Dockerfiles. +This folder stores all Dockerfiles required for the project. It is imperative that both images have the same dependencies and versions for consistency and reproducibility across environments. ## Dockerfile - -The `Dockerfile` file is the one used for building the production image. +The Dockerfile is used for building the production image that will be published for production environments. It should only contain what is strictly required to run the application. ## Dockerfile.dev - -The `Dockerfile.dev` file is the one used for building the development environment image. - -## Dockerfile.cicd - -The `Dockerfile.cicd` file is the one used for building the CI/CD environment image. +The Dockerfile.dev is used for building the development (e.g., devcontainers) and CI environment image. It includes all dependencies included in Dockerfile and others needed for development and testing.