diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d4da889..57f9ae4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,7 @@ name: ci env: - EARTHLY_TOKEN: ${{ secrets.EARTHLY_TOKEN }} - DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} - DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} - FORCE_COLOR: 1 + REGISTRY: ghcr.io + IMAGE_NAME: peapescarte/pescarte-plataforma on: push: @@ -14,35 +12,182 @@ on: jobs: lint: runs-on: ubuntu-latest + env: + MIX_ENV: dev + strategy: + matrix: + otp: [26.2.5] + elixir: [1.16.2] steps: - - uses: earthly/actions-setup@v1 + - uses: actions/checkout@v4 + + - uses: erlef/setup-beam@v1 with: - version: v0.8.14 - - uses: actions/checkout@v2 - - name: Run build - run: earthly --ci --build-arg MIX_ENV=dev +ci + otp-version: ${{ matrix.otp }} + elixir-version: ${{ matrix.elixir }} + + - name: Cache Elixir deps + uses: actions/cache@v1 + id: deps-cache + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + + - name: Cache Elixir _build + uses: actions/cache@v1 + id: build-cache + with: + path: _build + key: ${{ runner.os }}-build-${{ matrix.otp }}-${{ matrix.elixir }}-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + + - name: Install deps + if: steps.deps-cache.outputs.cache-hit != 'true' + run: | + mix local.rebar --force + mix local.hex --force + mix deps.get --only ${{ env.MIX_ENV }} + + - name: Compile deps + if: steps.build-cache.outputs.cache-hit != 'true' + run: mix deps.compile --warnings-as-errors + + - name: Run compiler checks + run: mix clean && mix compile --force --warning-as-errors + + - name: Run formatter check + run: mix format --check-formatted + + - name: Run static analysis + run: mix credo --strict test: runs-on: ubuntu-latest + env: + SUPABASE_KEY: "super-ci-key" + SUPABASE_URL: "http://localhost:123" + DATABASE_USER: "peapescarte" + DATABASE_PASS: "peapescarte" + MIX_ENV: test + strategy: + matrix: + otp: [26.2.5] + elixir: [1.16.2] + services: + postgres: + image: postgres:15 + ports: + - 5432:5432 + env: + POSTGRES_USER: peapescarte + POSTGRES_PASSWORD: peapescarte + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - - uses: earthly/actions-setup@v1 + - uses: actions/checkout@v4 + + - uses: erlef/setup-beam@v1 + with: + otp-version: ${{ matrix.otp }} + elixir-version: ${{ matrix.elixir }} + + - name: Cache Elixir deps + uses: actions/cache@v1 + id: deps-cache with: - version: v0.8.14 - - uses: actions/checkout@v2 - - name: Run build - run: earthly -P --ci --build-arg MIX_ENV=test +test + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + + - name: Cache Elixir _build + uses: actions/cache@v1 + id: build-cache + with: + path: _build + key: ${{ runner.os }}-build-${{ matrix.otp }}-${{ matrix.elixir }}-${{ hashFiles(format('{0}{1}', github.workspace, '/mix.lock')) }} + - name: Install deps + if: steps.deps-cache.outputs.cache-hit != 'true' + run: | + mix local.rebar --force + mix local.hex --force + mix deps.get --only ${{ env.MIX_ENV }} + + - name: Compile deps + if: steps.build-cache.outputs.cache-hit != 'true' + run: mix deps.compile --warnings-as-errors + + - name: Run tests + run: mix test + + build-dev: + runs-on: ubuntu-latest + needs: test + if: success() && github.ref == 'refs/heads/main' + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - uses: actions/checkout@v4 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.GHCR_USER }} + password: ${{ secrets.GHCR_TOKEN }} + + - name: Build and push Docker image (DEV) + id: push + uses: docker/build-push-action@v6 + with: + context: . + from: ./Dockerfile + push: true + tags: ${{ env.IMAGE_NAME }}:dev + build-args: MIX_ENV="dev" + target: builder + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true build-prod: runs-on: ubuntu-latest needs: test if: success() && github.ref == 'refs/heads/main' + permissions: + contents: read + packages: write + attestations: write + id-token: write steps: - - uses: earthly/actions-setup@v1 + - uses: actions/checkout@v4 + + - name: Log in to the Container registry + uses: docker/login-action@v3 with: - version: v0.8.14 - - uses: actions/checkout@v2 - - name: Docker Login - run: echo "$DOCKERHUB_TOKEN" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin - - name: Run build - run: earthly -P --ci --push --build-arg GITHUB_REPO=${{ github.repository }} +docker + registry: ${{ env.REGISTRY }} + username: ${{ secrets.GHCR_USER }} + password: ${{ secrets.GHCR_TOKEN }} + - name: Build and push Docker image (PROD) + id: push + uses: docker/build-push-action@v6 + with: + context: . + from: ./Dockerfile + push: true + tags: ${{ env.IMAGE_NAME }}:prod + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true diff --git a/Dockerfile b/Dockerfile index d575fbc6..e3e273f3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ ARG ELIXIR_VERSION=1.16.0 ARG OTP_VERSION=26.1.2 ARG ALPINE_VERSION=3.18.4 +ARG MIX_ENV=prod ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-alpine-${ALPINE_VERSION}" ARG RUNNER_IMAGE="alpine:${ALPINE_VERSION}" @@ -17,9 +18,6 @@ RUN apk add --no-cache build-base gcc curl git wget nodejs npm RUN mix local.hex --force && \ mix local.rebar --force -# set build ENV -ENV MIX_ENV="prod" - # install mix dependencies COPY mix.exs mix.lock ./ RUN mix deps.get --only $MIX_ENV diff --git a/Earthfile b/Earthfile deleted file mode 100644 index 2d28c529..00000000 --- a/Earthfile +++ /dev/null @@ -1,69 +0,0 @@ -VERSION 0.7 - -deps: - ARG ELIXIR=1.16.0 - ARG OTP=26.1.2 - ARG ALPINE_VERSION=3.18.4 - ARG MIX_ENV=test - FROM hexpm/elixir:${ELIXIR}-erlang-${OTP}-alpine-${ALPINE_VERSION} - RUN apk update --no-cache - RUN apk add --no-cache build-base gcc git curl - WORKDIR /src - COPY mix.exs mix.lock ./ - COPY --dir config . # check .earthlyignore - RUN mix local.rebar --force - RUN mix local.hex --force - RUN mix deps.get - RUN mix deps.compile - COPY --dir lib . - SAVE ARTIFACT /src/deps AS LOCAL deps - -ci: - FROM +deps --MIX_ENV=dev - COPY .credo.exs . - COPY .formatter.exs . - RUN mix clean - RUN mix compile --warning-as-errors - RUN mix format --check-formatted - RUN mix credo --strict - -test: - FROM +deps --MIX_ENV=test - RUN apk add postgresql-client - COPY --dir config ./ - RUN MIX_ENV=test mix deps.compile - COPY docker-compose.ci.yml ./docker-compose.yml - COPY mix.exs mix.lock ./ - COPY .env-sample ./ - COPY --dir lib priv test ./ - - WITH DOCKER --compose docker-compose.yml - RUN while ! pg_isready --host=localhost --port=5432 --quiet; do sleep 1; done; \ - SUPABASE_KEY="123" SUPABASE_URL="123" DATABASE_USER="peapescarte" DATABASE_PASS="peapescarte" mix test - END - -docker-prod: - FROM DOCKERFILE . - ARG GITHUB_REPO - SAVE IMAGE --push ghcr.io/$GITHUB_REPO:prod - -docker-dev: - FROM +deps --MIX_ENV=dev - RUN apk update --no-cache - RUN apk add --no-cache inotify-tools nodejs npm - ENV MIX_ENV=dev - COPY --dir config ./ - RUN mix deps.compile - COPY --dir assets ./ - COPY --dir priv ./ - RUN mix compile - CMD ["mix", "dev"] - ARG GITHUB_REPO=peapescarte/pescarte-plataforma - SAVE IMAGE --push ghcr.io/$GITHUB_REPO:dev - -docker-dev-arm: - BUILD --platform=linux/arm64/v8 +docker-dev - -docker: - BUILD +docker-dev - BUILD +docker-prod diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml deleted file mode 100644 index 1f43c860..00000000 --- a/docker-compose.ci.yml +++ /dev/null @@ -1,13 +0,0 @@ -version: "3.8" - -services: - database: - image: postgres:14.6 - container_name: plataforma_pescarte_database - environment: - - POSTGRES_USER=peapescarte - - POSTGRES_PASSWORD=peapescarte - ports: - - 5432:5432 - volumes: - - .postgres:/var/lib/postgresql/data