Skip to content
This repository was archived by the owner on Jan 28, 2025. It is now read-only.

Commit b2cc97f

Browse files
authored
feat(nextjs-component): add build.postBuildCommands input to execute any command or script post-build (#772)
1 parent 6e6821b commit b2cc97f

File tree

6 files changed

+57
-3
lines changed

6 files changed

+57
-3
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ The fourth cache behaviour handles next API requests `api/*`.
438438
| build.cwd | `string` | `./` | Override the current working directory |
439439
| build.enabled | `boolean` | `true` | Same as passing `build:false` but from within the config |
440440
| build.env | `object` | `{}` | Add additional environment variables to the script |
441+
| build.postBuildCommands | `Array` | `[]` | Any commands to run post-build and pre-deploy. For example, you can run any custom code on the `.serverless_nextjs` directory. Only applies during execution of the `serverless` command. |
441442
| cloudfront | `object` | `{}` | Inputs to be passed to [aws-cloudfront](https://github.com/serverless-components/aws-cloudfront) |
442443
| certificateArn | `string` | `` | Specific certificate ARN to use for CloudFront distribution. Helpful if you have a wildcard SSL cert you wish to use. This currently works only in tandem with the `domain` input. Please check [custom CloudFront configuration](https://github.com/serverless-nextjs/serverless-next.js#custom-cloudfront-configuration) for how to specify `certificate` without needing to use the `domain` input (note that doing so will override any certificate due to the domain input). |
443444
| domainType | `string` | `"both"` | Can be one of: `"apex"` - apex domain only, don't create a www subdomain. `"www"` - www domain only, don't create an apex subdomain.`"both"` - create both www and apex domains when either one is provided. |
@@ -629,6 +630,7 @@ In summary, you will have to create a new S3 bucket and set it up with static we
629630
To allow your app to access the defined environment variables, you need to expose them via the `next.config.js` as outlined [here](https://nextjs.org/docs/api-reference/next.config.js/environment-variables).
630631

631632
Given a `serverless.yml` like this
633+
632634
```yml
633635
myApp:
634636
inputs:
@@ -642,9 +644,9 @@ your next.config.js should look like that:
642644
```js
643645
module.exports = {
644646
env: {
645-
API_HOST: process.env.API_HOST,
646-
},
647-
}
647+
API_HOST: process.env.API_HOST
648+
}
649+
};
648650
```
649651

650652
## Contributing
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log("Successfully run a post-build command script.");
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
next-app:
22
component: "../../serverless-components/nextjs-component"
3+
inputs:
4+
build:
5+
postBuildCommands: ["node scripts/post-build-test.js"]
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import NextjsComponent from "../src/component";
2+
import { BuildOptions } from "../types";
3+
4+
describe("Post-build tests", () => {
5+
let component: NextjsComponent;
6+
let buildOptions: BuildOptions;
7+
8+
beforeEach(async () => {
9+
component = new NextjsComponent();
10+
buildOptions = {
11+
cmd: "true",
12+
args: []
13+
};
14+
});
15+
16+
it("executes post-build command successfully", async () => {
17+
buildOptions.postBuildCommands = ["true"];
18+
19+
await component.postBuild({ build: buildOptions });
20+
});
21+
22+
it("fails to execute post-build command", async () => {
23+
buildOptions.postBuildCommands = ["false"];
24+
25+
await expect(
26+
component.postBuild({ build: buildOptions })
27+
).rejects.toThrow();
28+
});
29+
});

packages/serverless-components/nextjs-component/src/component.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import type {
2121
LambdaType,
2222
LambdaInput
2323
} from "../types";
24+
import { execSync } from "child_process";
2425

2526
// Message when deployment is explicitly skipped
2627
const SKIPPED_DEPLOY = "SKIPPED_DEPLOY";
@@ -37,6 +38,7 @@ class NextjsComponent extends Component {
3738
): Promise<DeploymentResult> {
3839
if (inputs.build !== false) {
3940
await this.build(inputs);
41+
await this.postBuild(inputs);
4042
}
4143

4244
return this.deploy(inputs);
@@ -210,6 +212,22 @@ class NextjsComponent extends Component {
210212
}
211213
}
212214

215+
/**
216+
* Run any post-build steps.
217+
* Useful to run any custom commands before deploying.
218+
* @param inputs
219+
*/
220+
async postBuild(inputs: ServerlessComponentInputs): Promise<void> {
221+
const buildOptions = inputs.build;
222+
223+
const postBuildCommands =
224+
(buildOptions as BuildOptions)?.postBuildCommands ?? [];
225+
226+
for (const command of postBuildCommands) {
227+
execSync(command, { stdio: "inherit" });
228+
}
229+
}
230+
213231
async deploy(
214232
inputs: ServerlessComponentInputs = {}
215233
): Promise<DeploymentResult> {

packages/serverless-components/nextjs-component/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export type BuildOptions = {
3434
cmd: string;
3535
args: string[];
3636
env?: Record<string, string>;
37+
postBuildCommands?: string[];
3738
};
3839

3940
export type LambdaType = "defaultLambda" | "apiLambda";

0 commit comments

Comments
 (0)