Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
3dbb647
feat(cli-internal): add assess, refactor, and generate-new commands
iliapolo Mar 17, 2026
6873cfc
chore: fix test
iliapolo Mar 17, 2026
16846fa
test(cli-internal): replace null-as-any logger with noOpLogger helper
iliapolo Mar 17, 2026
317737f
feat(cli-internal): print validation report on failure
iliapolo Mar 17, 2026
c0a38cb
refactor(cli-internal): classify auth stacks by resource type
iliapolo Mar 17, 2026
ff63d5d
Merge branch 'gen2-migration' into epolon/refactor-after-rollback-auth
iliapolo Mar 19, 2026
d309cc8
refactor(cli-internal): split auth refactorers and improve resource m…
iliapolo Mar 20, 2026
2d45f9e
revert(cli-internal): remove trailing-newline normalization from sani…
iliapolo Mar 20, 2026
e136a67
Merge branch 'gen2-migration' into epolon/refactor-after-rollback-auth
iliapolo Mar 20, 2026
6a4bed3
chore: remove merge markers
iliapolo Mar 20, 2026
5cbbfa7
chore: cleanup
iliapolo Mar 20, 2026
db785ac
feat(cli-internal): group plan operations by resource
iliapolo Mar 21, 2026
8827079
fix(cli-internal): tweak plan resource group display
iliapolo Mar 21, 2026
5562032
feat(cli-internal): refine plan display and support UserPool Groups r…
iliapolo Mar 21, 2026
5811ef7
docs: add commit OOM prevention and scratch file cleanup
iliapolo Mar 21, 2026
28f8dd4
feat(cli-internal): add changeset preview and move table to refactor …
iliapolo Mar 21, 2026
9d2e090
fix(cli-internal): improve changeset report formatting
iliapolo Mar 21, 2026
9554e90
refactor(cli-internal): use cli-table3 for move table and fix changes…
iliapolo Mar 21, 2026
bee6cae
feat(cli-internal): validate stack updates via changeset during refac…
iliapolo Mar 21, 2026
e569cd2
test(cli-internal): fix gen2-migration refactor tests
iliapolo Mar 21, 2026
960e6e5
refactor(cli-internal): improve refactor workflow resilience
iliapolo Mar 22, 2026
c511745
refactor(cli-internal): add physicalResourceId to MoveMapping
iliapolo Mar 22, 2026
09d2be8
refactor(cli-internal): hoist computation out of callbacks and simpli…
iliapolo Mar 22, 2026
195f982
refactor(cli-internal): consolidate CFN operations into Cfn class
iliapolo Mar 22, 2026
e1a83f6
refactor(cli-internal): add SpinningLogger to Cfn class
iliapolo Mar 22, 2026
7d4374e
refactor(cli-internal): clean up refactorer operations
iliapolo Mar 22, 2026
5fd4d21
refactor(cli-internal): harden refactor workflow for multi-stack moves
iliapolo Mar 22, 2026
8e9b42b
refactor(cli-internal): improve refactor logging, remove caching, add…
iliapolo Mar 22, 2026
45878ff
fix(cli-internal): defer template resolution to execution time in ref…
iliapolo Mar 22, 2026
b2d1b05
refactor(cli-internal): move template manipulation into Cfn.refactor …
iliapolo Mar 22, 2026
2698a8f
refactor(cli-internal): use SDK ResourceMapping and strip all DependsOn
iliapolo Mar 22, 2026
aaaa376
fix(cli-internal): handle absent holding stacks and defer template fe…
iliapolo Mar 22, 2026
a41cf12
refactor(cli-internal): share Cfn instance, enable rollback resolutio…
iliapolo Mar 23, 2026
32091b1
test(cli-internal): update refactor tests for new interfaces
iliapolo Mar 23, 2026
3ba4939
fix(cli-internal): prevent test hangs with missing mocks and async fixes
iliapolo Mar 23, 2026
a66f7cc
test(cli-internal): fix all refactor tests — 17 suites, 92 tests pass
iliapolo Mar 23, 2026
ee86aa1
docs(cli-internal): update JSDoc for refactor workflow changes
iliapolo Mar 23, 2026
5545ea4
docs(cli-internal): fix remaining JSDoc inaccuracies
iliapolo Mar 23, 2026
cec05b7
test(cli-internal): make CloudFormation mock stateful with template map
iliapolo Mar 23, 2026
50ef166
test(cli-internal): reorganize refactor tests to mirror source structure
iliapolo Mar 23, 2026
8b3d080
chore: revert snapshots
iliapolo Mar 23, 2026
e5c5b13
fix(cli-internal): clone empty holding template to prevent cross-refa…
iliapolo Mar 23, 2026
1e72d2a
docs: add coding guideline for module-level mutable constants
iliapolo Mar 23, 2026
1525461
chore: geo codegen
Mar 23, 2026
98a01d3
chore(cli-internal): remove duplicate ResourceMapping, add dictionary…
iliapolo Mar 23, 2026
676324f
style(cli-internal): consistent property order in ResourceMapping obj…
iliapolo Mar 23, 2026
20a1610
chore: regen fitness tracker snapshots
iliapolo Mar 24, 2026
8c3aac1
chore: update snapshots
iliapolo Mar 24, 2026
8822035
refactor(cli-internal): simplify beforeMove/afterMove to take stack ID
iliapolo Mar 24, 2026
72fdab7
test(cli-internal): fix tests for beforeMove/afterMove signature change
iliapolo Mar 24, 2026
d398c77
chore: recapture snapshot
iliapolo Mar 24, 2026
6ffd821
chore: update snapshots
iliapolo Mar 24, 2026
7c2aedb
docs(cli-internal): update refactor.md for beforeMove/afterMove changes
iliapolo Mar 24, 2026
398db04
test(cli-internal): add buildResourceMappings edge case tests
iliapolo Mar 24, 2026
576a347
test(cli-internal): add targetLogicalId and match tests for all refac…
iliapolo Mar 24, 2026
b9e4ef7
docs(cli-internal): document resource mapping happy and unhappy paths
iliapolo Mar 24, 2026
e3d532d
fix(cli-internal): skip holding stack resources already present in be…
iliapolo Mar 24, 2026
c1f546f
feat(cli-internal): delete holding stack after rollback if only place…
iliapolo Mar 24, 2026
1733750
Merge remote-tracking branch 'origin/epolon/refactor-after-rollback-a…
Mar 24, 2026
7cc0ce0
chore: adding generate snapshots
Mar 24, 2026
7813ad6
Merge branch 'gen2-migration' into epolon/refactor-after-rollback-auth
iliapolo Mar 24, 2026
0920d3e
chore: bring back discussions from gen2-migration
iliapolo Mar 24, 2026
84584cf
chore: update snapshots
iliapolo Mar 24, 2026
824c65f
chore: update package
Mar 24, 2026
d448d6b
fix(cli-internal): align tests with gen2-migration merge changes
iliapolo Mar 24, 2026
ca04573
Merge remote-tracking branch 'origin/epolon/refactor-after-rollback-a…
Mar 24, 2026
447de62
chore: pre-refactor snapshots
Mar 24, 2026
7b639f0
test(cli-internal): update store-locator snapshot for generate
Mar 24, 2026
79fdcd1
chore: update stack naming with geo prefix
Mar 25, 2026
b3b3ae7
fix(cli-internal): mark GeofenceCollection as unsupported for refactor
Mar 25, 2026
f3dc182
chore: update yarn.lock
Mar 25, 2026
9b28406
chore: update snapshot.ts
Mar 25, 2026
97051dc
chore: test scripts
Mar 27, 2026
e68815b
chore: gen1 test scripts
Mar 27, 2026
f9b0d23
chore: gen2 script
Mar 27, 2026
40a22d3
chore: merge gen2-migration and fix merge resolution errors
Mar 28, 2026
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
1 change: 1 addition & 0 deletions amplify-migration-apps/_test-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"name": "shared-test-utils",
"private": true,
"version": "0.0.0",
"type": "module",
"dependencies": {
"@aws-sdk/client-cognito-identity-provider": "^3.936.0",
"aws-amplify": "^6.15.8"
Expand Down
8 changes: 4 additions & 4 deletions amplify-migration-apps/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ function stackNameFromArn(arnOrName: string): string {
return arnOrName;
}

async function downloadRecursive(stackNameOrArn: string, targetDir: string, appId: string, appName: string): Promise<void> {
async function downloadRecursive(stackNameOrArn: string, targetDir: string): Promise<void> {
const stackName = stackNameFromArn(stackNameOrArn);

const template = await fetchTemplate(stackName);
Expand All @@ -148,7 +148,7 @@ async function downloadRecursive(stackNameOrArn: string, targetDir: string, appI

const nestedIds = await fetchNestedStacks(stackName);
for (const nestedId of nestedIds) {
await downloadRecursive(nestedId, targetDir, appId, appName);
await downloadRecursive(nestedId, targetDir);
}
}

Expand All @@ -165,8 +165,8 @@ async function capturePreRefactor(appName: string, amplifyAppName?: string, gen2
const targetDir = path.resolve(path.join(__dirname, appName, '_snapshot.pre.refactor'));
resetDir(targetDir);

await downloadRecursive(gen2RootStack, targetDir, app.appId!, app.name!);
await downloadRecursive(gen1RootStack, targetDir, app.appId!, app.name!);
await downloadRecursive(gen2RootStack, targetDir);
await downloadRecursive(gen1RootStack, targetDir);
}

async function capturePostRefactor(appName: string, deployedAppPath: string): Promise<void> {
Expand Down
310 changes: 310 additions & 0 deletions amplify-migration-apps/store-locator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
# Store Locator (Amplify Gen1)

![](./images/app.png)

A store locator app that displays store locations on an interactive map powered by AWS Amplify Geo and Amazon Location Service. It uses Maps for rendering store locations, Place Index (Location Search) for address search, and Geofence Collections for users to define virtual perimeters around store areas.

## Install Dependencies

```console
npm install
```

## Initialize Environment

```console
amplify init
```

```console
⚠️ For new projects, we recommend starting with AWS Amplify Gen 2, our new code-first developer experience. Get started at https://docs.amplify.aws/react/start/quickstart/
✔ Do you want to continue with Amplify Gen 1? (y/N) · yes
✔ Why would you like to use Amplify Gen 1? · Prefer not to answer
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project storeLocator
The following configuration will be applied:

Project information
| Name: storeLocator
| Environment: main
| Default editor: Visual Studio Code
| App type: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: dist
| Build Command: npm run-script build
| Start Command: npm run-script start

? Initialize the project with the above configuration? No
? Enter a name for the environment main
? Choose your default editor: Visual Studio Code
✔ Choose the type of app that you're building · javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path: src
? Distribution Directory Path: dist
? Build Command: npm run-script build
? Start Command: npm run-script start
Using default provider awscloudformation
? Select the authentication method you want to use: AWS profile

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use default
```

## Add Categories

### Auth

Cognito-based auth using email. Create Cognito user pool groups for Geofences and add post confirmation lambda trigger to add users to the group.

```console
amplify add auth
```

```console
? Do you want to use the default authentication and security configuration? Manual configuration
? Select the authentication/authorization services that you want to use: User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for i
mages or other content, Analytics, and more)
? Provide a friendly name for your resource that will be used to label this category in the project: (accept default value)
? Enter a name for your identity pool. (accept default value)
? Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) No
? Do you want to enable 3rd party authentication providers in your identity pool? No
? Provide a name for your user pool: (accept default value)
? How do you want users to be able to sign in? Email
? Do you want to add User Pool Groups? Yes
? Provide a name for your user pool group: storeLocatorAdmin
? Do you want to add another User Pool Group No
? Sort the user pool groups in order of preference · storeLocatorAdmin
? Do you want to add an admin queries API? No
? Multifactor authentication (MFA) user login options: OFF
? Email based user registration/forgot password: Enabled (Requires per-user email entry at registration)
? Specify an email verification subject: Your verification code
? Specify an email verification message: Your verification code is {####}
? Do you want to override the default password policy for this User Pool? No
? What attributes are required for signing up? Email
? Specify the app's refresh token expiration period (in days): 100
? Do you want to specify the user attributes this app can read and write? No
? Do you want to enable any of the following capabilities? Add User to Group
? Do you want to use an OAuth flow? No
? Do you want to configure Lambda Triggers for Cognito? Yes
? Which triggers do you want to enable for Cognito Post Confirmation
? What functionality do you want to use for Post Confirmation Add User To Group
? Enter the name of the group to which users will be added. · storeLocatorAdmin
```

### Geo - Map

Map resource for displaying store locations using Amazon Location Service.

```console
amplify add geo
```

```console
? Select which capability you want to add: Map (visualize the geospatial data)
✔ Provide a name for the Map: · storeLocatorMap
✔ Restrict access by? · Both
✔ Who can access this Map? · Authorized and Guest users
Must pick at least 1 of 1 options. Selecting all options [storeLocatorAdmin]
Available advanced settings:
- Map style & Map data provider (default: Streets provided by Esri)

✔ Do you want to configure advanced settings? (y/N) · no
```

### Geo - Location Search

Search index for searching places and addresses.

```console
amplify add geo
```

```console
? Select which capability you want to add: Location search (search by places, addresses, coordinates)
✔ Provide a name for the location search index (place index): · storeLocatorSearch
✔ Restrict access by? · Both
✔ Who can access this search index? · Authorized and Guest users
Must pick at least 1 of 1 options. Selecting all options [storeLocatorAdmin]
Available advanced settings:
- Search data provider (default: HERE)
- Search result storage location (default: no result storage)

✔ Do you want to configure advanced settings? (y/N) · no
```

### Geo - Geofence

```console
amplify add geo
```

```console
? Select which capability you want to add: Geofencing (visualize virtual perimeters)
✔ Provide a name for the Geofence Collection: · storeLocatorGeofence
Must pick at least 1 of 1 options. Selecting all options [storeLocatorAdmin]
✔ What kind of access do you want for storeLocatorAdmin users? Select ALL that apply: · Read geofence, Create/Update geofence, Delete geofence, List geofences
```

```console
amplify push
```

```console
Current Environment: main

┌──────────┬──────────────────────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name │ Operation │ Provider plugin │
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
│ Auth │ storelocatorcff4360f │ Create │ awscloudformation │
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
│ Geo │ storeLocatorMap │ Create │ awscloudformation │
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
│ Auth │ userPoolGroups │ Create │ awscloudformation │
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
│ Function │ storelocatorcff4360fPostConfirmation │ Create │ awscloudformation │
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
│ Geo │ storeLocatorGeofence │ Create │ awscloudformation │
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
│ Geo │ storeLocatorSearch │ Create │ awscloudformation │
└──────────┴──────────────────────────────────────────┴───────────┴───────────────────┘

✔ Are you sure you want to continue? (Y/n) · yes
```

## Publish Frontend

To publish the frontend, leverage the Amplify hosting console. First push everything to the `main` branch:

```console
git add .
git commit -m "feat: gen1"
git push origin main
```

Next, accept all the default values and follow the getting started wizard to connect your repo and branch. Wait for the deployment to finish successfully.

![](./images/hosting-get-started.png)
![](./images/add-main-branch.png)
![](./images/deploying-main-branch.png)

Wait for the deployment to finish successfully.

## Migrating to Gen2

> Based on https://github.com/aws-amplify/amplify-cli/blob/gen2-migration/GEN2_MIGRATION_GUIDE.md

> [!WARNING]
> Migration is not fully supported for this app because the geo category doesn't support refactoring yet.
> This guide ends at the `generate` step.

First install the experimental amplify CLI package that provides the migration commands.

```console
npm install @aws-amplify/cli-internal-gen2-migration-experimental-alpha
```

Now run them:

```console
npx amplify gen2-migration lock
```

```console
git checkout -b gen2-main
npx amplify gen2-migration generate
```

**Edit in `./src/main.tsx`:**

```diff
- import amplifyconfig from './amplifyconfiguration.json';
+ import amplifyconfig from '../amplify_outputs.json';
```

```console
git add .
git commit -m "feat: migrate to gen2"
git push origin gen2-main
```

**Edit in `./amplify/auth/storelocatorcff4360fPostConfirmation/resource.ts`:**

```diff
- memoryMB: 128,
- runtime: 22
+ memoryMB: 512,
+ runtime: 22,
+ resourceGroupName: 'auth'
```

**Edit in `./amplify/auth/storelocatorcff4360fPostConfirmation/index.js`:**

The Gen1 dynamic `require(`./${name}`)` doesn't work with esbuild bundling in the Amplify build pipeline (`Module not found in bundle: ./add-to-group`). Replace with a static import:

```diff
- const moduleNames = process.env.MODULES.split(',');
- /**
- * The array of imported modules.
- */
- const modules = moduleNames.map((name) => require(`./${name}`));
+ import * as addToGroup from './add-to-group';
+
+ const modules = [addToGroup];
```

```diff
- exports.handler = async (event, context) => {
+ export async function handler(event, context) {
```

**Edit in `./amplify/auth/storelocatorcff4360fPostConfirmation/add-to-group.js`:**

```diff
- const {
- CognitoIdentityProviderClient,
- AdminAddUserToGroupCommand,
- GetGroupCommand,
- CreateGroupCommand,
- } = require('@aws-sdk/client-cognito-identity-provider');
+ import {
+ CognitoIdentityProviderClient,
+ AdminAddUserToGroupCommand,
+ GetGroupCommand,
+ CreateGroupCommand,
+ } from '@aws-sdk/client-cognito-identity-provider';
```

```diff
- exports.handler = async (event) => {
+ export const handler = async (event) => {
```

**Edit in `./amplify/auth/resource.ts`:**

```diff
- triggers: {
- postConfirmation: storelocatorcff4360fPostConfirmation
- },
+ triggers: {
+ postConfirmation: storelocatorcff4360fPostConfirmation
+ },
+ access: (allow) => [
+ allow.resource(storelocatorcff4360fPostConfirmation).to([
+ "addUserToGroup",
+ "manageGroups",
+ ]),
+ ],
```

Now connect the `gen2-main` branch to the hosting service:

![](./images/add-gen2-main-branch.png)
![](./images/deploying-gen2-main-branch.png)

Wait for the deployment to finish successfully.

**The guide ends here because the geo category doesn't support refactoring yet.**
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# amplify
.amplify
amplify_outputs*
amplifyconfiguration*
aws-exports*
node_modules
build
dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: 1
backend:
phases:
build:
commands:
- "# Execute Amplify CLI with the helper script"
- npm ci --cache .npm --prefer-offline
- npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
frontend:
phases:
preBuild:
commands:
- npm install
build:
commands:
- npm run build
artifacts:
baseDirectory: dist
files:
- "**/*"
cache:
paths:
- node_modules/**/*
Loading
Loading