generated from amazon-archives/__template_Apache-2.0
-
Notifications
You must be signed in to change notification settings - Fork 102
add new e2e test for validating backwards compatibility of amplify outputs #2009
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
bf4d873
add new e2e test for validating backwards compatibility of amplify ou…
Amplifiyer 3d33c5a
add changeset
Amplifiyer 54e8687
try this
Amplifiyer ee3ed9b
try this
Amplifiyer 19f1d56
try this
Amplifiyer 66af993
try this
Amplifiyer be19a1d
try this
Amplifiyer 07c7501
PR Updates
Amplifiyer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| --- | ||
| --- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| name: setup_baseline_version | ||
| description: Set up a baseline or "previous" version of the library for testing. Mostly useful for backwards compatibility | ||
| outputs: | ||
| baseline_dir: | ||
| description: 'Path where baseline project directory is setup' | ||
| value: ${{ steps.move_baseline_version.outputs.baseline_dir }} | ||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: Get baseline commit sha | ||
| id: get_baseline_commit_sha | ||
| shell: bash | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| if [[ ${{ github.event_name }} == 'push' ]]; then | ||
| # The SHA of the most recent commit on ref before the push. | ||
| baseline_commit_sha="${{ github.event.before }}" | ||
| elif [[ ${{ github.event_name }} == 'pull_request' ]]; then | ||
| # The SHA of the HEAD commit on base branch. | ||
| baseline_commit_sha="${{ github.event.pull_request.base.sha }}" | ||
| elif [[ ${{ github.event_name }} == 'schedule' ]] || [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then | ||
| # The SHA of the parent of HEAD commit on main branch. | ||
| # This assumes linear history of main branch, i.e. one parent. | ||
| # These events have only information about HEAD commit, hence the need for lookup. | ||
| baseline_commit_sha=$(gh api /repos/${{ github.repository }}/commits/${{ github.sha }} | jq -r '.parents[0].sha') | ||
| else | ||
| echo Unable to determine baseline commit sha; | ||
| exit 1; | ||
| fi | ||
| echo baseline commit sha is $baseline_commit_sha; | ||
| echo "baseline_commit_sha=$baseline_commit_sha" >> "$GITHUB_OUTPUT"; | ||
| - name: Checkout baseline version | ||
| uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # version 4.1.4 | ||
| with: | ||
| ref: ${{ steps.get_baseline_commit_sha.outputs.baseline_commit_sha }} | ||
| - uses: ./.github/actions/setup_node | ||
| - name: Install and build baseline version | ||
| shell: bash | ||
| run: | | ||
| npm ci | ||
| npm run build | ||
| - name: Move baseline version | ||
| id: move_baseline_version | ||
| shell: bash | ||
| run: | | ||
| BASELINE_DIR=$(mktemp -d) | ||
| # Command below makes shell include .hidden files in file system commands (i.e. mv). | ||
| # This is to make sure that .git directory is moved with the repo content. | ||
| shopt -s dotglob | ||
| mv ./* $BASELINE_DIR | ||
| echo "baseline_dir=$BASELINE_DIR" >> "$GITHUB_OUTPUT"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
212 changes: 212 additions & 0 deletions
212
packages/integration-tests/src/test-e2e/amplify_outputs_backwards_compatibility.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,212 @@ | ||
| import { after, before, describe, it } from 'node:test'; | ||
| import { execa } from 'execa'; | ||
| import path from 'path'; | ||
| import { TestBranch, amplifyAppPool } from '../amplify_app_pool.js'; | ||
| import { BackendIdentifier } from '@aws-amplify/plugin-types'; | ||
| import { | ||
| CloudFormationClient, | ||
| DeleteStackCommand, | ||
| } from '@aws-sdk/client-cloudformation'; | ||
| import fsp from 'fs/promises'; | ||
| import { e2eToolingClientConfig } from '../e2e_tooling_client_config.js'; | ||
| import { NpmProxyController } from '../npm_proxy_controller.js'; | ||
| import assert from 'assert'; | ||
| import os from 'os'; | ||
| import { generateClientConfig } from '@aws-amplify/client-config'; | ||
| import { BackendIdentifierConversions } from '@aws-amplify/platform-core'; | ||
| import { amplifyAtTag } from '../constants.js'; | ||
|
|
||
| void describe('client config backwards compatibility', () => { | ||
| let branchBackendIdentifier: BackendIdentifier; | ||
| let testBranch: TestBranch; | ||
| let cfnClient: CloudFormationClient; | ||
| let tempDir: string; | ||
| let baselineDir: string; | ||
| let baselineNpmProxyController: NpmProxyController; | ||
| let currentNpmProxyController: NpmProxyController; | ||
|
|
||
| before(async () => { | ||
| assert.ok( | ||
| process.env.BASELINE_DIR, | ||
| 'BASELINE_DIR environment variable must be set and point to amplify-backend repo at baseline version' | ||
| ); | ||
| baselineDir = process.env.BASELINE_DIR; | ||
|
|
||
| tempDir = await fsp.mkdtemp( | ||
| path.join(os.tmpdir(), 'test-amplify-outputs-backwards-compatibility') | ||
| ); | ||
|
|
||
| console.log(`Temp dir is ${tempDir}`); | ||
|
|
||
| cfnClient = new CloudFormationClient(e2eToolingClientConfig); | ||
| baselineNpmProxyController = new NpmProxyController(baselineDir); | ||
| currentNpmProxyController = new NpmProxyController(); | ||
| testBranch = await amplifyAppPool.createTestBranch(); | ||
| branchBackendIdentifier = { | ||
| namespace: testBranch.appId, | ||
| name: testBranch.branchName, | ||
| type: 'branch', | ||
| }; | ||
| }); | ||
|
|
||
| after(async () => { | ||
| await cfnClient.send( | ||
| new DeleteStackCommand({ | ||
| StackName: BackendIdentifierConversions.toStackName( | ||
| branchBackendIdentifier | ||
| ), | ||
| }) | ||
| ); | ||
| await fsp.rm(tempDir, { recursive: true }); | ||
|
|
||
| await baselineNpmProxyController.tearDown(); | ||
| await currentNpmProxyController.tearDown(); | ||
| }); | ||
|
|
||
| const deploy = async (): Promise<void> => { | ||
| await execa( | ||
| 'npx', | ||
| [ | ||
| 'ampx', | ||
| 'pipeline-deploy', | ||
| '--branch', | ||
| branchBackendIdentifier.name, | ||
| '--appId', | ||
| branchBackendIdentifier.namespace, | ||
| ], | ||
| { | ||
| cwd: tempDir, | ||
| stdio: 'inherit', | ||
| env: { | ||
| CI: 'true', | ||
| }, | ||
| } | ||
| ); | ||
| }; | ||
|
|
||
| const reinstallDependencies = async (): Promise<void> => { | ||
| await fsp.rm(path.join(tempDir, 'node_modules'), { | ||
| recursive: true, | ||
| force: true, | ||
| }); | ||
| await fsp.unlink(path.join(tempDir, 'package-lock.json')); | ||
|
|
||
| await execa('npm', ['install'], { | ||
| cwd: tempDir, | ||
| stdio: 'inherit', | ||
| }); | ||
| }; | ||
|
|
||
| const assertGenerateClientConfigAPI = async ( | ||
| type: 'baseline' | 'current' | ||
| ) => { | ||
| try { | ||
| assert.ok( | ||
| await generateClientConfig(branchBackendIdentifier, '1'), | ||
| `outputs v1 failed to be generated for an app created with ${type} library version` | ||
| ); | ||
| } catch (e) { | ||
| throw new Error( | ||
| `outputs v1 failed to be generated for an app created with ${type} library version. Error: ${JSON.stringify( | ||
| e | ||
| )}` | ||
| ); | ||
| } | ||
| try { | ||
| assert.ok( | ||
| await generateClientConfig(branchBackendIdentifier, '1.1'), | ||
| `outputs v1.1 failed to be generated for an app created with ${type} library version` | ||
| ); | ||
| } catch (e) { | ||
| throw new Error( | ||
| `outputs v1.1 failed to be generated for an app created with ${type} library version. Error: ${JSON.stringify( | ||
| e | ||
| )}` | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| const assertGenerateClientConfigCommand = async ( | ||
| type: 'baseline' | 'current' | ||
| ) => { | ||
| await execa( | ||
| 'npx', | ||
| [ | ||
| 'ampx', | ||
| 'generate', | ||
| 'outputs', | ||
| '--stack', | ||
| BackendIdentifierConversions.toStackName(branchBackendIdentifier), | ||
| ], | ||
| { | ||
| cwd: tempDir, | ||
| stdio: 'inherit', | ||
| } | ||
| ); | ||
|
|
||
| const fileSize = ( | ||
| await fsp.stat(path.join(tempDir, 'amplify_outputs.json')) | ||
| ).size; | ||
| assert.ok( | ||
| fileSize > 100, // Validate that it's not just a shim | ||
| `outputs file should not be empty when generating for a ${ | ||
| type === 'baseline' ? 'new' : 'old' | ||
| } new app with the ${type} version` | ||
| ); | ||
| }; | ||
|
|
||
| void it('outputs generation should be backwards and forward compatible', async () => { | ||
| // build an app using previous (baseline) version | ||
| await baselineNpmProxyController.setUp(); | ||
| await execa('npm', ['create', amplifyAtTag, '--yes'], { | ||
| cwd: tempDir, | ||
| stdio: 'inherit', | ||
| }); | ||
|
|
||
| // Replace backend.ts to add custom outputs without version as well. | ||
| await fsp.writeFile( | ||
| path.join(tempDir, 'amplify', 'backend.ts'), | ||
| `import { defineBackend } from '@aws-amplify/backend'; | ||
| import { auth } from './auth/resource'; | ||
| import { data } from './data/resource'; | ||
|
|
||
| const backend = defineBackend({ | ||
| auth, | ||
| data, | ||
| }); | ||
|
|
||
| backend.addOutput({ | ||
| custom: { | ||
| someCustomOutput: 'someCustomOutputValue', | ||
| }, | ||
| }); | ||
| ` | ||
| ); | ||
| await deploy(); | ||
| await baselineNpmProxyController.tearDown(); | ||
|
|
||
| // Generate the outputs using the current version for apps built with baseline version | ||
|
|
||
| // 1. via CLI command | ||
| await currentNpmProxyController.setUp(); | ||
| await reinstallDependencies(); | ||
| await assertGenerateClientConfigCommand('current'); | ||
|
|
||
| // 2. via API. | ||
| await assertGenerateClientConfigAPI('current'); | ||
|
|
||
| // Re-deploy the app using the current version now | ||
| await deploy(); | ||
|
|
||
| // Generate the outputs using the baseline version for apps built with current version | ||
|
|
||
| // 1. via CLI command | ||
| await currentNpmProxyController.tearDown(); | ||
| await baselineNpmProxyController.setUp(); | ||
| await reinstallDependencies(); | ||
| await assertGenerateClientConfigCommand('baseline'); | ||
|
|
||
| // 2. via API. | ||
| await assertGenerateClientConfigAPI('baseline'); | ||
| }); | ||
| }); | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need these try-catch blocks ?
would
assert.doesNotReject()work here ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it will, but the error messages were a bit cryptic. This way we can add more assertions on the result of the API as well in the future.