Skip to content

Commit

Permalink
feat(cms): update to payload 3 and fix breaking changes
Browse files Browse the repository at this point in the history
closed COD-268
  • Loading branch information
hakalb committed Feb 18, 2025
1 parent 8a81f0c commit 54fe8b5
Show file tree
Hide file tree
Showing 151 changed files with 7,799 additions and 6,150 deletions.
1 change: 1 addition & 0 deletions .github/workflows/fly-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ jobs:
secrets: |
INFISICAL_CLIENT_ID=${{ secrets.INFISICAL_READ_CLIENT_ID }}
INFISICAL_CLIENT_SECRET=${{ secrets.INFISICAL_READ_CLIENT_SECRET }}
INFISICAL_PROJECT_ID=${{ secrets.INFISICAL_PROJECT_ID }}
opt-out-depot-builder: ${{ vars.FLY_OPT_OUT_DEPOT }}
env:
# Postgres preview cluster defined in `github.json`
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ apps/**/pnpm-lock.yaml

# Next.js
.next
out
out
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"editor.formatOnSave": true,
"eslint.validate": ["json"],
"files.associations": {
".*.*__tmpl__": "plaintext"
".*.*__tmpl__": "plaintext",
"*.css": "tailwindcss"
},
"jest.runMode": {
"coverage": true,
Expand Down
1 change: 0 additions & 1 deletion apps/cms/.env.docker
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,4 @@ SIGNATURE_SECRET=secret
# Normally injected by deployment action
APP_NAME=cms
DEPLOY_ENV=development
NODE_ENV=development
PR_NUMBER=
10 changes: 2 additions & 8 deletions apps/cms/.env.local
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,13 @@ SIGNATURE_SECRET=supers3cret
# Default values that are bundled with the application and not served by Infisical
APP_NAME=cdwr-cms
DEPLOY_ENV=development
NODE_ENV=development
PR_NUMBER=

# Print debug log for Express middleware when set to `true`
REQUEST_DEBUG=

# Force a migration action regardsless of the current state
MIGRATE_ACTION=default

# Infisical credentials
INFISICAL_CLIENT_ID=
INFISICAL_CLIENT_SECRET=
INFISICAL_SERVICE_TOKEN=
INFISICAL_SERVICE_TOKEN=st.42f83310-0c17-4294-aeb5-8e6c6f6b0669.878af64f19553b410d72df53280b5839.f91d15102f3967a5cac383c6a23400b9
INFISICAL_PROJECT_ID=

# Postgres credentials required to initialize the local database correctly
POSTGRES_DB=cms
Expand Down
8 changes: 0 additions & 8 deletions apps/cms/.env.serve

This file was deleted.

30 changes: 30 additions & 0 deletions apps/cms/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"jsc": {
"target": "es2017",
"parser": {
"syntax": "typescript",
"decorators": true,
"dynamicImport": true
},
"transform": {
"decoratorMetadata": true,
"legacyDecorator": true
},
"keepClassNames": true,
"externalHelpers": true,
"loose": true
},
"module": {
"type": "commonjs"
},
"sourceMaps": true,
"exclude": [
"jest.config.ts",
".*\\.spec.tsx?$",
".*\\.test.tsx?$",
"./src/jest-setup.ts$",
"./**/jest-setup.ts$",
".*.js$",
".*.d.ts$"
]
}
71 changes: 42 additions & 29 deletions apps/cms/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,47 +1,60 @@
FROM node:22-slim AS base

FROM base AS builder
FROM node:20-alpine AS base

FROM base AS deps
# Check the link to understand why libc6-compat might be needed
# https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Copy package.json first to leverage Docker cache for dependencies
COPY package.json ./

# TODO: Remove once cms is updated to Payload v3
# Downgrade to React v18 to be compatible with Payload v2
RUN \
sed -i 's/react": "19.0.0",/react": "18.3.1",/g' package.json && \
sed -i 's/react-dom": "19.0.0",/react-dom": "18.3.1",/g' package.json && \
sed -i 's/react-router-dom": "6.11.2",/react-router-dom": "5.3.4",/g' package.json && \
sed -i 's/@types\/react": "19.0.0",/@types\/react": "18.3.12",/g' package.json && \
sed -i 's/@types\/react-dom": "19.0.0",/@types\/react-dom": "18.3.1",/g' package.json

RUN npm install
# Check the link regarding legacy-peer-deps
# https://payloadcms.com/docs/getting-started/installation#1-install-the-relevant-packages
RUN npm i --legacy-peer-deps

# Copy the dependencies to builder stage.
# Lock file is important for Nx to calculate a correct project graph.
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/package-lock.json ./package-lock.json
COPY . .

# The lock file is needed when building the app so remove it from `.gitignore`
# The lock file is hidden from the build process when included in the .gitignore file.
# Since package-lock.json is needed when building the app, we'll remove it from .gitignore.
RUN sed -i '/package-lock.json/d' .gitignore

RUN npx nx build cms
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Comment the following line in case you want to enable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED 1

FROM base

ENV NODE_ENV=production
# Path is relative to workdir, where `node` is invoked
ENV PAYLOAD_CONFIG_PATH="dist/apps/cms/server/apps/cms/src/payload.config.js"
RUN npx nx build cms

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

COPY --from=builder /app/dist/apps/cms/package.json ./
ENV NODE_ENV production
# Disable telemetry during runtime.
ENV NEXT_TELEMETRY_DISABLED 1

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/apps/cms/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/apps/cms/.next/static ./apps/cms/.next/static
COPY --from=builder --chown=nextjs:nodejs /app/apps/cms/public ./apps/cms/public

RUN npm install --omit=dev
# Set the correct ownership
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN chown -R nextjs:nodejs /app

COPY --from=builder /app/dist ./dist
COPY --from=builder /app/.infisical.json ./
# Needed as part of the tsconfig paths workaround (and it's not pretty?)
# Must be located where the node command is invoked
COPY --from=builder /app/tsconfig.base.json ./
USER nextjs

EXPOSE 3000
CMD ["node", "dist/apps/cms/server/main.js"]

ENV PORT 3000

ENV HOSTNAME="0.0.0.0"
CMD ["node", "apps/cms/server.js"]
7 changes: 3 additions & 4 deletions apps/cms/Dockerfile.dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.DS_Store
.git
.github

# Config
.settings
Expand All @@ -19,15 +18,15 @@ dist
node_modules
tmp

# Lock files
# Don't let host lock files detect wrong package manager in Dockerfile
bun.lockb
package-lock.json
pnpm-lock.yaml
yarn.lock

# Apps
# Other apps
/apps/*
!/apps/cms

# Prevent overriding Infisical environment variables
# Target environment variables for local development
.env.*
41 changes: 24 additions & 17 deletions apps/cms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,48 @@

Payload application generated by Nx plugin [`@cdwr/nx-payload`](https://github.com/codeware-sthlm/codeware/tree/master/packages/nx-payload).

## Getting started

### Start Postgres database in Docker
## Start the application in Docker

```sh
npx nx dx:start postgres
npx nx dx:start cms
```

### Serve the application in development mode
Visit <http://localhost:3000>

### Stop and remove Docker containers

```sh
npx nx serve cms
npx nx dx:stop cms
```

Visit <http://localhost:3000>
> Database is stored in persistent volume, so containers can be stopped and started without loosing the data
## Maintenance
## Serve application in development mode

### Delete database and run migrations
First start the database in Docker when needed

```sh
npx nx payload cms migrate:fresh
npx nx dx:mongodb cms
```

### Generate seed data
or

Seed data is stored in environment-specific TypeScript files in
```sh
npx nx dx:postgres cms
```

- `libs/shared/data-access/seed/src/lib/seed-data`.
Then serve the application in development mode

You can remove the existing seed data and save the empty object to the file to generate new seed data.
```sh
npx nx dev cms
```

## Running tests

```sh
npx nx seed cms
npx nx test cms
```

# specific environment
DEPLOY_ENV=preview npx nx seed cms
```sh
npx nx lint cms
```
9 changes: 3 additions & 6 deletions apps/cms/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Only for Development.
# Should be started from workspace root.

# Hard coded environment variables is a valid workaround for using Postgres image locally.
# Hard coded environment variables is a valid workaround for using database images locally.
# Should match what we get from `process.env.DATABASE_URL`.

services:
Expand All @@ -17,9 +17,7 @@ services:
networks:
- local
volumes:
- type: volume
source: db_postgres
target: /var/lib/postgresql/data
- pgdata:/var/lib/postgresql/data

cms:
container_name: cms
Expand All @@ -42,5 +40,4 @@ networks:
driver: bridge

volumes:
db_postgres:
driver: local
pgdata:
6 changes: 6 additions & 0 deletions apps/cms/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
declare module '*.svg' {
const content: any;
export const ReactComponent: any;
export default content;
}
10 changes: 10 additions & 0 deletions apps/cms/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
displayName: 'cms',
preset: '../../jest.preset.js',
transform: {
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest',
'^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/next/babel'] }]
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/apps/cms'
};
16 changes: 16 additions & 0 deletions apps/cms/mocks/next-headers.mock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as nextHeaders from 'next/headers';

type MockNextHeaders = typeof nextHeaders;

/**
* Mock for `next/headers`.
*
* Returns `headers` with empty object.
*/
const mockNextHeaders: Partial<MockNextHeaders> = {
headers: jest.fn().mockResolvedValue({})
};

export const { headers } = mockNextHeaders;

export default mockNextHeaders;
17 changes: 17 additions & 0 deletions apps/cms/mocks/next-image.mock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';

/**
* Mock for default import of `next/image`.
*
* Returns `HTMLImageElement` with `alt` set to `Mocked Next Image`.
*/
export const mockNextImage = () => ({
__esModule: true,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
default: (props: any) => {
// eslint-disable-next-line @next/next/no-img-element
return <img {...props} alt="Mocked Next Image" />;
}
});

export default mockNextImage;
12 changes: 12 additions & 0 deletions apps/cms/mocks/payload-config.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Mock for default import of `payload.config`.
*
* Returns `routes` with `admin` set to `/admin`.
*/
export const mockPayloadConfig = Promise.resolve({
routes: {
admin: '/admin'
}
});

export default mockPayloadConfig;
21 changes: 21 additions & 0 deletions apps/cms/mocks/payload.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as payload from 'payload';

type MockPayload = typeof payload;
type Payload = payload.Payload;

/**
* Mock for `payload`.
*
* Returns `getPayload` with `auth` set to unknown user.
*/
const mockPayload: Partial<MockPayload> = {
getPayload: jest.fn().mockResolvedValue({
auth: jest
.fn()
.mockResolvedValue({ user: null } as Partial<Payload['auth']>)
} as Partial<Payload>)
};

export const { getPayload } = mockPayload;

export default mockPayload;
5 changes: 5 additions & 0 deletions apps/cms/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
Loading

0 comments on commit 54fe8b5

Please sign in to comment.