Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: CI

on:
push:
branches:
- main
pull_request:

permissions:
actions: read
contents: read

jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
filter: tree:0
fetch-depth: 0

# This enables task distribution via Nx Cloud
# Run this command as early as possible, before dependencies are installed
# Learn more at https://nx.dev/ci/reference/nx-cloud-cli#npx-nxcloud-startcirun
# Connect your workspace by running "nx connect" and uncomment this line to enable task distribution
# - run: npx nx start-ci-run --distribute-on="3 linux-medium-js" --stop-agents-after="e2e-ci"

# Cache node_modules
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- run: npx playwright install --with-deps
- uses: nrwl/nx-set-shas@v4

# Prepend any command with "nx-cloud record --" to record its logs to Nx Cloud
# - run: npx nx-cloud record -- echo Hello World
# When you enable task distribution, run the e2e-ci task instead of e2e
- run: npx nx affected -t lint test build e2e
# Nx Cloud recommends fixes for failures to help you get CI green faster. Learn more: https://nx.dev/ci/features/self-healing-ci
#- run: npx nx fix-ci
# if: always()
18 changes: 18 additions & 0 deletions .github/workflows/fly-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/

name: Fly Deploy
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy app
runs-on: ubuntu-latest
concurrency: deploy-group # optional: ensure only one action runs at a time
steps:
- uses: actions/checkout@v4
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ vitest.config.*.timestamp*

.cursor
.vscode

*.env
31 changes: 31 additions & 0 deletions apps/movies-api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@
"projectType": "application",
"tags": ["type:app", "scope:api"],
"targets": {
"build": {
"configurations": {
"production": {
"externalDependencies": [
"@nestjs/microservices",
"@nestjs/microservices/microservices-module",
"@nestjs/websockets/socket-module",
"class-transformer",
"class-validator",
"cache-manager",
"cache-manager/package.json",
"tslib"
],
"assets": [
"apps/movies-api/src/assets",
"apps/movies-api/src/fly.toml",
"apps/movies-api/src/Dockerfile",
"apps/movies-api/src/.dockerignore"
]
}
}
},
"serve": {
"executor": "@nx/js:node",
"defaultConfiguration": "development",
Expand All @@ -29,6 +51,15 @@
"options": {
"jestConfig": "apps/movies-api/jest.config.ts"
}
},
"deploy": {
"executor": "@nx-workshop/internal-plugin:fly-deploy",
"outputs": [],
"options": {
"distLocation": "dist/apps/movies-api",
"flyAppName": "moritzmeinhardt"
},
"dependsOn": [{ "target": "build", "projects": "self", "params": "forward" }]
}
}
}
54 changes: 54 additions & 0 deletions apps/movies-api/src/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
dist
tmp
/out-tsc

# dependencies
node_modules

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

# misc
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings

# System Files
.DS_Store
Thumbs.db

.nx/cache
.nx/workspace-data

.angular

vite.config.*.timestamp*
vitest.config.*.timestamp*
.cursor/rules/nx-rules.mdc
.github/instructions/nx.instructions.md

.cursor
.vscode

*.env
43 changes: 43 additions & 0 deletions apps/movies-api/src/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# syntax = docker/dockerfile:1

# Adjust NODE_VERSION as desired
ARG NODE_VERSION=22.18.0
FROM node:${NODE_VERSION}-slim AS base

LABEL fly_launch_runtime="NestJS"

# NestJS app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV="production"

# Install pnpm
ARG PNPM_VERSION=10.15.1
RUN npm install -g pnpm@$PNPM_VERSION


# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3

# Install node modules
COPY .yarnrc package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod=false

# Copy application code
COPY . .


# Final stage for app image
FROM base

# Copy built application
COPY --from=build /app /app

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD [ "pnpm", "run", "start" ]
22 changes: 22 additions & 0 deletions apps/movies-api/src/fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# fly.toml app configuration file generated for moritzmeinhardt on 2025-09-12T12:58:06+02:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'moritzmeinhardt'
primary_region = 'lax'

[build]

[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = 'stop'
auto_start_machines = true
min_machines_running = 0
processes = ['app']

[[vm]]
memory = '1gb'
cpu_kind = 'shared'
cpus = 1
2 changes: 2 additions & 0 deletions apps/movies-app/.local.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SURGE_TOKEN=c14ff6a9c614e5d376de64407437df80
SURGE_DOMAIN=https://moritzmeinhardt-angular-connect.surge.sh
16 changes: 16 additions & 0 deletions apps/movies-app/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,22 @@
"buildTarget": "movies-app:build",
"staticFilePath": "dist/apps/movies-app/browser"
}
},
"windows-deploy": {
"executor": "nx:run-commands",
"outputs": [],
"options": {
"command": "npx surge dist/apps/movies-app/browser %SURGE_DOMAIN% --token %SURGE_TOKEN%"
},
"dependsOn": ["build"]
},
"deploy": {
"executor": "nx:run-commands",
"outputs": [],
"options": {
"command": "npx surge dist/apps/movies-app/browser ${SURGE_DOMAIN} --token ${SURGE_TOKEN}"
},
"dependsOn": ["build"]
}
}
}
1 change: 1 addition & 0 deletions apps/movies-app/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const routes: Routes = [
import('@nx-workshop/movies/feature-movie-list').then(
m => m.MovieListPageComponent
),
title: 'Movies List' // <-- Add this
},
{
path: 'list/genre/:id',
Expand Down
12 changes: 10 additions & 2 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
const nx = require('@nx/eslint-plugin');

module.exports = [
{
files: ['**/*.json'],
// Override or add rules here
rules: {},
languageOptions: {
parser: require('jsonc-eslint-parser'),
},
},

...nx.configs['flat/base'],
...nx.configs['flat/typescript'],
...nx.configs['flat/javascript'],
Expand Down Expand Up @@ -78,7 +87,6 @@ module.exports = [
},
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
rules: {
},
rules: {},
},
];
2 changes: 1 addition & 1 deletion exercises/advanced/deploy-target-and-custom-executor.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ As we want those three files above to be copied rather than re-generated every t
"assets": [
"apps/movies-api/src/assets",
"apps/movies-api/src/fly.toml",
"apps/movies-api/src/Dcokerfile",
"apps/movies-api/src/Dockerfile",
"apps/movies-api/src/.dockerignore",
],
```
Expand Down
11 changes: 11 additions & 0 deletions libs/internal-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# internal-plugin

This library was generated with [Nx](https://nx.dev).

## Building

Run `nx build internal-plugin` to build the library.

## Running unit tests

Run `nx test internal-plugin` to execute the unit tests via [Jest](https://jestjs.io).
28 changes: 28 additions & 0 deletions libs/internal-plugin/eslint.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const baseConfig = require('../../eslint.config.js');

module.exports = [
...baseConfig,
{
files: ['**/*.json'],
rules: {
'@nx/dependency-checks': [
'error',
{
ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}'],
},
],
},
languageOptions: {
parser: require('jsonc-eslint-parser'),
},
},
{
files: ['**/package.json', '**/package.json', '**/executors.json'],
rules: {
'@nx/nx-plugin-checks': 'error',
},
languageOptions: {
parser: require('jsonc-eslint-parser'),
},
},
];
9 changes: 9 additions & 0 deletions libs/internal-plugin/executors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"executors": {
"fly-deploy": {
"implementation": "./src/fly-deploy/fly-deploy",
"schema": "./src/fly-deploy/schema.json",
"description": "fly-deploy executor"
}
}
}
10 changes: 10 additions & 0 deletions libs/internal-plugin/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
displayName: 'internal-plugin',
preset: '../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/libs/internal-plugin',
};
13 changes: 13 additions & 0 deletions libs/internal-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "@nx-workshop/internal-plugin",
"version": "0.0.1",
"private": true,
"type": "commonjs",
"main": "./src/index.js",
"types": "./src/index.d.ts",
"dependencies": {
"@nx/devkit": "21.5.2",
"tslib": "^2.3.0"
},
"executors": "./executors.json"
}
Loading