From c04bbc4fcf421ebba81a3994db328f09ee2697bc Mon Sep 17 00:00:00 2001 From: eahefnawy Date: Tue, 24 Sep 2024 14:47:11 +0000 Subject: [PATCH 1/4] feat(web): add custom scripts plugin --- website/package.json | 4 +-- website/scripts.js | 60 ++++++++++++++++++++++++++++++++++++++++++ website/serverless.yml | 2 +- 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 website/scripts.js diff --git a/website/package.json b/website/package.json index 3b181cf..890859b 100644 --- a/website/package.json +++ b/website/package.json @@ -2,13 +2,13 @@ "name": "website", "version": "1.0.0", "main": "index.js", + "type": "module", "license": "MIT", "dependencies": { "express": "^4.19.2", "serverless-http": "^3.2.0" }, "devDependencies": { - "serverless-domain-manager": "^7.4.0", - "serverless-plugin-scripts": "^1.0.2" + "serverless-domain-manager": "^7.4.0" } } diff --git a/website/scripts.js b/website/scripts.js new file mode 100644 index 0000000..2588090 --- /dev/null +++ b/website/scripts.js @@ -0,0 +1,60 @@ +import { execSync } from "child_process"; + +class Scripts { + constructor(serverless) { + this.serverless = serverless; + this.commands = {}; + this.hooks = {}; + + this.defineCommands(); + this.defineHooks(); + } + + getConfig() { + const service = this.serverless.service; + return service.custom && service.custom.scripts; + } + + defineCommands() { + const config = this.getConfig(); + const commands = config && config.commands; + if (!commands) return; + + for (const name of Object.keys(commands)) { + if (!this.commands[name]) { + this.commands[name] = { lifecycleEvents: [] }; + } + this.commands[name].lifecycleEvents.push(name); + + this.hooks[`${name}:${name}`] = this.runCommand.bind(this, name); + } + } + + defineHooks() { + const config = this.getConfig(); + const hooks = config && config.hooks; + if (!hooks) return; + + for (const name of Object.keys(hooks)) { + this.hooks[name] = this.runHook.bind(this, name); + } + } + + runCommand(name) { + const commands = this.getConfig().commands; + const command = commands[name]; + this.execute(command); + } + + runHook(name) { + const hooks = this.getConfig().hooks; + const hook = hooks[name]; + this.execute(hook); + } + + execute(command) { + execSync(command, { stdio: ["ignore", "ignore", "inherit"] }); + } +} + +export default Scripts; diff --git a/website/serverless.yml b/website/serverless.yml index 495549b..29ca833 100644 --- a/website/serverless.yml +++ b/website/serverless.yml @@ -5,8 +5,8 @@ provider: runtime: nodejs20.x plugins: - - serverless-plugin-scripts - serverless-domain-manager + - ./scripts build: esbuild: true From 7ab434d6aec96ad5b7349ba7734fb08f3d4c3685 Mon Sep 17 00:00:00 2001 From: eahefnawy Date: Tue, 24 Sep 2024 15:28:10 +0000 Subject: [PATCH 2/4] feat(web): inhert script process logs if verbose or debug --- .github/workflows/main.yml | 10 +--------- website/scripts.js | 13 +++++++++++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dfdd3c7..e19a67b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,20 +1,13 @@ name: Deploy main branch on: - push: - branches: - - main pull_request: branches: - main - pull_request_target: - types: - - closed jobs: deploy: name: deploy - if: github.event_name != 'pull_request_target' || github.event.pull_request.merged != true runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -35,14 +28,13 @@ jobs: - name: Serverless Deploy uses: serverless/github-action@v4 with: - args: deploy --stage ${{ github.event.pull_request.number && 'pr-${{ github.event.pull_request.number }}' || 'prod' }} + args: deploy --stage pr-${{ github.event.pull_request.number }} env: SERVERLESS_LICENSE_KEY: ${{ secrets.SERVERLESS_LICENSE_KEY }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} remove: name: remove - if: github.event.pull_request.merged == true runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/website/scripts.js b/website/scripts.js index 2588090..46cc9b0 100644 --- a/website/scripts.js +++ b/website/scripts.js @@ -1,8 +1,11 @@ import { execSync } from "child_process"; class Scripts { - constructor(serverless) { + constructor(serverless, options, utils) { this.serverless = serverless; + this.options = options; + this.utils = utils; + this.commands = {}; this.hooks = {}; @@ -53,7 +56,13 @@ class Scripts { } execute(command) { - execSync(command, { stdio: ["ignore", "ignore", "inherit"] }); + let stdio = ["ignore", "ignore", "inherit"]; + + if (this.options.verbose || this.options.debug) { + stdio = "inherit"; + } + + execSync(command, { stdio }); } } From b25d04159f721a654bedd425b312ff54e929e30a Mon Sep 17 00:00:00 2001 From: eahefnawy Date: Tue, 24 Sep 2024 15:51:39 +0000 Subject: [PATCH 3/4] chore(GA): revert GA changes --- .github/workflows/main.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e19a67b..dfdd3c7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,13 +1,20 @@ name: Deploy main branch on: + push: + branches: + - main pull_request: branches: - main + pull_request_target: + types: + - closed jobs: deploy: name: deploy + if: github.event_name != 'pull_request_target' || github.event.pull_request.merged != true runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -28,13 +35,14 @@ jobs: - name: Serverless Deploy uses: serverless/github-action@v4 with: - args: deploy --stage pr-${{ github.event.pull_request.number }} + args: deploy --stage ${{ github.event.pull_request.number && 'pr-${{ github.event.pull_request.number }}' || 'prod' }} env: SERVERLESS_LICENSE_KEY: ${{ secrets.SERVERLESS_LICENSE_KEY }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} remove: name: remove + if: github.event.pull_request.merged == true runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 From 03e6fb9ae3f662c356bd60d60444ef1638d2681b Mon Sep 17 00:00:00 2001 From: eahefnawy Date: Thu, 26 Sep 2024 09:19:06 +0000 Subject: [PATCH 4/4] chore(website): added inline comments --- package-lock.json | 9 +-------- website/scripts.js | 18 ++++++++++++++++-- website/serverless.yml | 6 ++++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index b6476ce..d85ae90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9564,12 +9564,6 @@ "node": ">=12.0" } }, - "node_modules/serverless-plugin-scripts": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/serverless-plugin-scripts/-/serverless-plugin-scripts-1.0.2.tgz", - "integrity": "sha512-+OL9fFz5r6BXNHfpu9MDLehS/haC0fy/T3V5uJsTfLAnNsn+PzM6BmvefUfWG372hBT7piTbywB1Vl1+4LmI5Q==", - "dev": true - }, "node_modules/serverlessinc-example": { "resolved": "", "link": true @@ -10831,8 +10825,7 @@ "serverless-http": "^3.2.0" }, "devDependencies": { - "serverless-domain-manager": "^7.4.0", - "serverless-plugin-scripts": "^1.0.2" + "serverless-domain-manager": "^7.4.0" } }, "website/app": { diff --git a/website/scripts.js b/website/scripts.js index 46cc9b0..d925186 100644 --- a/website/scripts.js +++ b/website/scripts.js @@ -1,10 +1,20 @@ import { execSync } from "child_process"; +/** + * This is a custom Serverless Framework Plugin that allows you to + * define and run custom scripts in your serverless.yml file, similar to npm scripts. + * For more information on creating custom plugins, see the documentation: + * https://www.serverless.com/framework/docs/guides/plugins/creating-plugins + * + * In this AI example, we need to run vite build script before deploying the website service. + * So we built this quick plugin, and loaded it in the serverless.yml file. + */ + class Scripts { constructor(serverless, options, utils) { this.serverless = serverless; - this.options = options; - this.utils = utils; + this.options = options; // CLI options are passed to the plugin + this.utils = utils; // Helper logging functions are passed to the plugin this.commands = {}; this.hooks = {}; @@ -56,12 +66,16 @@ class Scripts { } execute(command) { + // By default, only show stderr in the terminal + // So that you can see any build errors that may occur let stdio = ["ignore", "ignore", "inherit"]; + // But in verbose or debug mode, we show all output if (this.options.verbose || this.options.debug) { stdio = "inherit"; } + // Execute the command/script in a child service execSync(command, { stdio }); } } diff --git a/website/serverless.yml b/website/serverless.yml index 29ca833..7825964 100644 --- a/website/serverless.yml +++ b/website/serverless.yml @@ -5,8 +5,8 @@ provider: runtime: nodejs20.x plugins: - - serverless-domain-manager - - ./scripts + - serverless-domain-manager # Load the community plugin for custom domains installed with npm + - ./scripts # Load our custom scripts plugin build: esbuild: true @@ -25,6 +25,8 @@ custom: apiType: http autoDomain: true enabled: ${param:customDomainNameEnabled} + + # This property is expected by our custom scripts plugin. scripts: hooks: # This hook builds the React App. It sets the environment variables for