Skip to content

Commit ca0f7b2

Browse files
committed
feat require Serverless Framework v4, drop v3 support BREAKING CHANGE: requires Serverless Framework v4; drops v3 support.
1 parent bda9abe commit ca0f7b2

9 files changed

Lines changed: 3171 additions & 5231 deletions

File tree

.github/workflows/ci.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ jobs:
2424
uses: actions/checkout@v6
2525
- name: Install dependencies
2626
run: npm ci
27+
- name: Verify no deep serverless/lib imports (guards #632)
28+
run: npm run verify:imports
2729
- name: Lint
2830
run: npm run lint
2931
- name: Tests
@@ -47,6 +49,13 @@ jobs:
4749
name: CFN Synthesis Tests
4850
runs-on: ubuntu-latest
4951
needs: tests
52+
# Serverless Framework v4 requires authentication for every CLI invocation,
53+
# including non-interactive CI. The e2e harness spawns `serverless package`,
54+
# so a license/access key must be present or the run will fail/prompt.
55+
# Add SERVERLESS_ACCESS_KEY (Dashboard > Settings > Access Keys) as a repo
56+
# secret. Free for individual developers / orgs under the revenue threshold.
57+
env:
58+
SERVERLESS_ACCESS_KEY: ${{ secrets.SERVERLESS_ACCESS_KEY }}
5059
steps:
5160
- name: Checkout code
5261
uses: actions/checkout@v6

e2e/README.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@ runs `serverless package` to produce a CloudFormation template, and
2121
asserts on the generated resources.
2222

2323
Critically, **these tests do not deploy anything to AWS** — they only
24-
exercise the synthesis path. That makes them fast (~3s per fixture),
25-
fork-safe (no AWS credentials required), and suitable to run on every
26-
PR.
24+
exercise the synthesis path. That makes them fast (~3s per fixture)
25+
and suitable to run on every PR. No AWS credentials are required.
26+
27+
> **Serverless Framework v4 requires authentication.** As of v4, every
28+
> CLI invocation (including the `serverless package` these tests run)
29+
> must be authenticated, even though nothing is deployed. You need a
30+
> Serverless **Access Key** or **License Key** — free for individual
31+
> developers and organizations under the revenue threshold. See
32+
> [Authentication](#authentication-serverless-v4) below.
2733
2834
## Running locally
2935

@@ -38,6 +44,24 @@ npm run test:all
3844
npx jest --config jest.e2e.config.ts basic-api-key
3945
```
4046

47+
### Authentication (Serverless v4)
48+
49+
Set a Serverless Access Key (or License Key) before running, otherwise
50+
the spawned `serverless package` will fail / prompt for login:
51+
52+
```bash
53+
# One-time interactive login (writes a key to your machine)
54+
npx serverless login
55+
56+
# …or set an explicit key for this shell / CI
57+
export SERVERLESS_ACCESS_KEY=... # from Dashboard > Settings > Access Keys
58+
# or
59+
export SERVERLESS_LICENSE_KEY=...
60+
```
61+
62+
The harness passes the current environment through to the CLI, so any
63+
of the above is sufficient.
64+
4165
## Adding a new test
4266

4367
1. Create a new example under `examples/<feature>/`:
@@ -90,3 +114,7 @@ A dedicated `e2e` job in `.github/workflows/ci.yml` runs the full
90114
synthesis test suite on every PR and push to `master` or `alpha`. It
91115
runs after the unit-test matrix completes successfully (no point
92116
running E2E if unit tests already failed).
117+
118+
The job reads `SERVERLESS_ACCESS_KEY` from repository secrets to
119+
authenticate the Serverless v4 CLI. Add it under
120+
**Settings > Secrets and variables > Actions** before this job can pass.

e2e/helpers/synthesize.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,33 @@ export function synthesize(exampleDir: string): SynthesizeResult {
9393
);
9494
}
9595

96-
const templatePath = path.join(
96+
// Serverless writes the synthesized template as
97+
// `cloudformation-template-update-stack.json`. We look it up defensively
98+
// (preferring the canonical name, then falling back to any
99+
// `cloudformation-template-*-stack.json`) so the harness is resilient to
100+
// any path/name nuance across Serverless Framework major versions.
101+
const canonical = path.join(
97102
packageDir,
98103
'cloudformation-template-update-stack.json',
99104
);
105+
let templatePath = canonical;
106+
if (!fs.existsSync(templatePath)) {
107+
const fallback = fs
108+
.readdirSync(packageDir)
109+
.find(
110+
(f) =>
111+
/^cloudformation-template-.*-stack\.json$/.test(f) &&
112+
f.endsWith('.json'),
113+
);
114+
if (fallback) {
115+
templatePath = path.join(packageDir, fallback);
116+
}
117+
}
100118
if (!fs.existsSync(templatePath)) {
101119
fs.rmSync(packageDir, { recursive: true, force: true });
102120
throw new Error(
103-
`CloudFormation template was not produced at ${templatePath}.`,
121+
`CloudFormation template was not produced in ${packageDir} ` +
122+
`(expected ${canonical} or a cloudformation-template-*-stack.json).`,
104123
);
105124
}
106125

0 commit comments

Comments
 (0)