Skip to content

Commit b435d50

Browse files
committed
feat: support e2e workflow on codebuild
1 parent ee9ac44 commit b435d50

File tree

12 files changed

+171
-36
lines changed

12 files changed

+171
-36
lines changed

.codebuild/e2e_workflow.yml

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
version: 0.2
33
env:
44
shell: bash
5-
compute-type: BUILD_GENERAL1_MEDIUM
5+
compute-type: BUILD_GENERAL1_LARGE
66
batch:
77
fast-fail: false
88
build-graph:
@@ -28,11 +28,20 @@ batch:
2828
compute-type: BUILD_GENERAL1_MEDIUM
2929
depend-on:
3030
- build_linux
31+
- identifier: build_app_swift
32+
buildspec: .codebuild/run_ios_modelgen_e2e_test.yml
33+
env:
34+
compute-type: BUILD_GENERAL1_LARGE
35+
variables:
36+
TEST_SUITE: src/__tests__/build-app-swift.test.ts
37+
CLI_REGION: us-east-2
38+
depend-on:
39+
- publish_to_local_registry
3140
- identifier: >-
3241
add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android
3342
buildspec: .codebuild/run_e2e_tests.yml
3443
env:
35-
compute-type: BUILD_GENERAL1_MEDIUM
44+
compute-type: BUILD_GENERAL1_LARGE
3645
variables:
3746
TEST_SUITE: >-
3847
src/__tests__/add-codegen-ios.test.ts|src/__tests__/configure-codegen-android.test.ts|src/__tests__/configure-codegen-js.test.ts|src/__tests__/graphql-codegen-android.test.ts
@@ -43,7 +52,7 @@ batch:
4352
graphql_codegen_js_remove_codegen_android_remove_codegen_ios_add_codegen_android
4453
buildspec: .codebuild/run_e2e_tests.yml
4554
env:
46-
compute-type: BUILD_GENERAL1_MEDIUM
55+
compute-type: BUILD_GENERAL1_LARGE
4756
variables:
4857
TEST_SUITE: >-
4958
src/__tests__/graphql-codegen-js.test.ts|src/__tests__/remove-codegen-android.test.ts|src/__tests__/remove-codegen-ios.test.ts|src/__tests__/add-codegen-android.test.ts
@@ -54,7 +63,7 @@ batch:
5463
configure_codegen_ios_datastore_modelgen_android_datastore_modelgen_js_feature_flags
5564
buildspec: .codebuild/run_e2e_tests.yml
5665
env:
57-
compute-type: BUILD_GENERAL1_MEDIUM
66+
compute-type: BUILD_GENERAL1_LARGE
5867
variables:
5968
TEST_SUITE: >-
6069
src/__tests__/configure-codegen-ios.test.ts|src/__tests__/datastore-modelgen-android.test.ts|src/__tests__/datastore-modelgen-js.test.ts|src/__tests__/feature-flags.test.ts
@@ -65,7 +74,7 @@ batch:
6574
graphql_codegen_ios_add_codegen_js_datastore_modelgen_ios_remove_codegen_js
6675
buildspec: .codebuild/run_e2e_tests.yml
6776
env:
68-
compute-type: BUILD_GENERAL1_MEDIUM
77+
compute-type: BUILD_GENERAL1_LARGE
6978
variables:
7079
TEST_SUITE: >-
7180
src/__tests__/graphql-codegen-ios.test.ts|src/__tests__/add-codegen-js.test.ts|src/__tests__/datastore-modelgen-ios.test.ts|src/__tests__/remove-codegen-js.test.ts
@@ -76,7 +85,7 @@ batch:
7685
datastore_modelgen_flutter_env_codegen_model_introspection_codegen_pull_codegen
7786
buildspec: .codebuild/run_e2e_tests.yml
7887
env:
79-
compute-type: BUILD_GENERAL1_MEDIUM
88+
compute-type: BUILD_GENERAL1_LARGE
8089
variables:
8190
TEST_SUITE: >-
8291
src/__tests__/datastore-modelgen-flutter.test.ts|src/__tests__/env-codegen.test.ts|src/__tests__/model-introspection-codegen.test.ts|src/__tests__/pull-codegen.test.ts
@@ -87,7 +96,7 @@ batch:
8796
push_codegen_ios_push_codegen_android_graphql_documents_generator_push_codegen_js
8897
buildspec: .codebuild/run_e2e_tests.yml
8998
env:
90-
compute-type: BUILD_GENERAL1_MEDIUM
99+
compute-type: BUILD_GENERAL1_LARGE
91100
variables:
92101
TEST_SUITE: >-
93102
src/__tests__/push-codegen-ios.test.ts|src/__tests__/push-codegen-android.test.ts|src/__tests__/graphql-documents-generator.test.ts|src/__tests__/push-codegen-js.test.ts
@@ -97,7 +106,7 @@ batch:
97106
- identifier: build_app_ts
98107
buildspec: .codebuild/run_e2e_tests.yml
99108
env:
100-
compute-type: BUILD_GENERAL1_MEDIUM
109+
compute-type: BUILD_GENERAL1_LARGE
101110
variables:
102111
TEST_SUITE: src/__tests__/build-app-ts.test.ts
103112
CLI_REGION: ap-southeast-1
@@ -106,7 +115,7 @@ batch:
106115
- identifier: cleanup_e2e_resources
107116
buildspec: .codebuild/cleanup_e2e_resources.yml
108117
env:
109-
compute-type: BUILD_GENERAL1_SMALL
118+
compute-type: BUILD_GENERAL1_MEDIUM
110119
depend-on:
111120
- >-
112121
add_codegen_ios_configure_codegen_android_configure_codegen_js_graphql_codegen_android

.codebuild/e2e_workflow_base.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 0.2
22
env:
33
shell: bash
4-
compute-type: BUILD_GENERAL1_MEDIUM
4+
compute-type: BUILD_GENERAL1_LARGE
55

66
batch:
77
fast-fail: false
@@ -28,3 +28,12 @@ batch:
2828
compute-type: BUILD_GENERAL1_MEDIUM
2929
depend-on:
3030
- build_linux
31+
- identifier: build_app_swift
32+
buildspec: .codebuild/run_ios_modelgen_e2e_test.yml
33+
env:
34+
compute-type: BUILD_GENERAL1_LARGE
35+
variables:
36+
TEST_SUITE: src/__tests__/build-app-swift.test.ts
37+
CLI_REGION: us-east-2
38+
depend-on:
39+
- publish_to_local_registry

.codebuild/run_e2e_tests.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@ env:
77
CI: true
88
CODEBUILD: true
99
NODE_OPTIONS: --max-old-space-size=8096
10-
# mock values to test artifact scanning
11-
ENV_VAR_WITH_SECRETS: 'MOCK_ENV_VAR_FOR_SCANNING_SECRETS'
12-
MOCK_ENV_VAR_FOR_SCANNING_SECRETS: 'abc123xyz'
10+
1311
phases:
1412
build:
1513
commands:
16-
# you can provide a codebuild source version to use old cache and skip all other jobs :)
1714
- source ./shared-scripts.sh && _runE2ETestsLinux
1815
post_build:
1916
commands:
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
version: 0.2
2+
env:
3+
shell: bash
4+
variables:
5+
AMPLIFY_DIR: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin
6+
AMPLIFY_PATH: /root/.npm-global/lib/node_modules/@aws-amplify/cli-internal/bin/amplify
7+
CI: true
8+
CODEBUILD: true
9+
NODE_OPTIONS: --max-old-space-size=8096
10+
phases:
11+
build:
12+
commands:
13+
- source ./shared-scripts.sh && _runE2ETestsLinux
14+
- export PATH_TO_MODELS=$CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/test-apps/swift/amplify/generated
15+
- cd $PATH_TO_MODELS && zip -r models.zip models
16+
- aws s3 cp $PATH_TO_MODELS/models.zip s3://$ARTIFACT_BUCKET_NAME/models.zip
17+
- export MODELS_S3_URL=$(aws s3 presign s3://$ARTIFACT_BUCKET_NAME/models.zip --expires-in 3600)
18+
- cd $CODEBUILD_SRC_DIR && ./.codebuild/scripts/run-ios-modelgen-e2e-test.sh
19+
post_build:
20+
commands:
21+
- aws sts get-caller-identity
22+
- source ./shared-scripts.sh && _scanArtifacts
23+
24+
artifacts:
25+
files:
26+
- $CODEBUILD_SRC_DIR/packages/amplify-codegen-e2e-tests/amplify-e2e-reports/*
27+
discard-paths: yes
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/bin/bash
2+
3+
REPO_OWNER="aws-amplify"
4+
REPO_NAME="amplify-codegen"
5+
6+
# Function to get the latest workflow run ID
7+
get_latest_run_id() {
8+
latest_run_id=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
9+
-H "Accept: application/vnd.github+json" \
10+
-H "X-GitHub-Api-Version: 2022-11-28" \
11+
"https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/actions/runs?event=workflow_dispatch&per_page=1" | \
12+
jq -r '.workflow_runs[0].id')
13+
echo "$latest_run_id"
14+
}
15+
16+
# Function to get the status of a workflow run
17+
get_run_status() {
18+
run_id="$1"
19+
run_status=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
20+
-H "Accept: application/vnd.github+json" \
21+
-H "X-GitHub-Api-Version: 2022-11-28" \
22+
"https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/actions/runs/$run_id" | \
23+
jq -r '.status')
24+
echo "$run_status"
25+
}
26+
27+
# Function to trigger a workflow dispatch event to run the e2e test
28+
trigger_workflow() {
29+
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \
30+
-H "Accept: application/vnd.github+json" \
31+
-H "X-GitHub-Api-Version: 2022-11-28" \
32+
"https://api.github.com/repos/$REPO_OWNER/$REPO_NAME/actions/workflows/build-swift-modelgen.yml/dispatches" \
33+
-d "{\"ref\":\"main\", \"inputs\":{\"MODELS_S3_URL\":\"${MODELS_S3_URL}\"}}"
34+
}
35+
36+
main() {
37+
trigger_workflow
38+
sleep 10 # Wait to allow for the workflow to be triggered
39+
40+
# Get the latest run ID and initial status
41+
latest_run_id=$(get_latest_run_id)
42+
echo "Latest run ID: $latest_run_id"
43+
latest_status=$(get_run_status "$latest_run_id")
44+
timeout=$((SECONDS + 600)) # 600 seconds = 10 minutes
45+
46+
# Continuously check for status until completion
47+
while [[ "$latest_status" != "completed" && "$SECONDS" -lt "$timeout" ]]; do
48+
echo "Test run status: $latest_status"
49+
sleep 10 # Wait before checking again
50+
latest_status=$(get_run_status "$latest_run_id")
51+
done
52+
53+
# Check if the run completed within the specified duration
54+
if [[ "$latest_status" != "completed" ]]; then
55+
echo "The test run did not complete within the specified duration."
56+
exit 1
57+
fi
58+
59+
# Check if the run failed and throw an error if it did
60+
if [[ "$latest_status" == "failure" ]]; then
61+
echo "The test run failed."
62+
exit 1
63+
else
64+
echo "The test run succeeded."
65+
fi
66+
}
67+
68+
main

packages/amplify-codegen-e2e-core/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@
3232
"rimraf": "^3.0.0",
3333
"strip-ansi": "^6.0.0",
3434
"throat": "^5.0.0",
35-
"uuid": "7.0.1"
35+
"uuid": "7.0.1",
36+
"ini": "^3.0.1"
37+
},
38+
"devDependencies": {
39+
"@types/ini": "^1.3.31"
3640
},
3741
"peerDependencies": {
3842
"@aws-amplify/amplify-cli-core": "^4.0.0",

packages/amplify-codegen-e2e-core/src/categories/codegen.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,20 @@ export function generateModelIntrospection(cwd: string, settings: { outputDir?:
147147
});
148148
}
149149

150+
export function generateModelIntrospectionWithError(cwd: string, errMessage: string, settings: { outputDir?: string} = {}): Promise<void> {
151+
return new Promise((resolve, reject) => {
152+
spawn(getCLIPath(), ['codegen', 'model-introspection', '--output-dir', settings.outputDir ?? ''], { cwd, stripColors: true })
153+
.wait(errMessage)
154+
.run((err: Error) => {
155+
if (!err) {
156+
resolve();
157+
} else {
158+
reject(err);
159+
}
160+
});
161+
});
162+
}
163+
150164
// CLI workflow to add codegen to non-Amplify JS project
151165
export function addCodegenNonAmplifyJS(cwd: string): Promise<void> {
152166
return new Promise((resolve, reject) => {

packages/amplify-codegen-e2e-core/src/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import * as path from 'path';
33
import * as fs from 'fs-extra';
44
import { spawnSync, execSync } from 'child_process';
55
import { v4 as uuid } from 'uuid';
6+
import * as ini from 'ini';
7+
import { pathManager } from '@aws-amplify/amplify-cli-core';
68

79
export * from './configure/';
810
export * from './init/';
@@ -29,7 +31,14 @@ export function getCLIPath(testingWithLatestCodebase = false) {
2931
}
3032

3133
export function isCI(): boolean {
32-
return process.env.CI && process.env.CIRCLECI ? true : false;
34+
return process.env.CI && (process.env.CIRCLECI || process.env.CODEBUILD) ? true : false;
35+
}
36+
37+
export function injectSessionToken(profileName: string) {
38+
const credentialsContents = ini.parse(fs.readFileSync(pathManager.getAWSCredentialsFilePath()).toString());
39+
credentialsContents[profileName] = credentialsContents[profileName] || {};
40+
credentialsContents[profileName].aws_session_token = process.env.AWS_SESSION_TOKEN;
41+
fs.writeFileSync(pathManager.getAWSCredentialsFilePath(), ini.stringify(credentialsContents));
3342
}
3443

3544
export function npmInstall(cwd: string) {

packages/amplify-codegen-e2e-tests/src/__tests__/build-app-swift.test.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import {
22
initProjectWithQuickstart,
33
DEFAULT_IOS_CONFIG,
4-
addApiWithBlankSchemaAndConflictDetection,
54
updateApiSchemaWithText,
65
generateModels,
7-
swiftBuild,
86
} from '@aws-amplify/amplify-codegen-e2e-core';
97
const { schemas } = require('@aws-amplify/graphql-schema-test-library');
10-
import { existsSync, writeFileSync, readdirSync, rmSync, readFileSync } from 'fs';
8+
import { writeFileSync, readdirSync, readFileSync } from 'fs';
119
import path from 'path';
1210

1311
const skip = new Set([
@@ -30,31 +28,25 @@ describe('build app - Swift', () => {
3028
});
3129

3230
afterEach(async () => {
33-
await rmSync(path.join(projectRoot, 'amplify', 'generated', 'models'), { recursive: true, force: true });
3431
writeFileSync(path.join(projectRoot, 'swift.xcodeproj', 'project.pbxproj'), projectPBXProjCache);
3532
});
3633

3734
Object.entries(schemas).forEach(([schemaName, schema]) => {
3835
// @ts-ignore
3936
const testName = `builds with ${schemaName}: ${schema.description}`;
37+
const schemaFolderName = schemaName.replace(/[^a-zA-Z0-9]/g, '');
38+
const outputDir = path.join(projectRoot, 'amplify', 'generated', 'models', schemaFolderName);
4039
const testFunction = async () => {
4140
// @ts-ignore
4241
const schemaText = `input AMPLIFY { globalAuthRule: AuthRule = { allow: public } }\n${schema.sdl}`;
4342
console.log(schemaText); // log so that circleci does not timeout
4443
updateApiSchemaWithText(projectRoot, 'amplifyDatasource', schemaText);
45-
await generateModels(projectRoot);
46-
await swiftBuild(projectRoot, { ...config, scheme: 'swift' });
44+
await generateModels(projectRoot, outputDir);
4745
};
4846
if (skip.has(schemaName)) {
4947
it.skip(testName, testFunction);
5048
} else {
5149
it(testName, testFunction);
5250
}
5351
});
54-
55-
it('fails build with syntax error', async () => {
56-
await generateModels(projectRoot);
57-
await writeFileSync(path.join(projectRoot, 'amplify', 'generated', 'models', 'AmplifyModels.swift'), 'foo\nbar');
58-
await expect(swiftBuild(projectRoot, { ...config })).rejects.toThrowError();
59-
});
6052
});

packages/amplify-codegen-e2e-tests/src/__tests__/model-introspection-codegen.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { addApiWithoutSchema, createNewProjectDir, generateModelIntrospection, initJSProjectWithProfile, updateApiSchema } from "@aws-amplify/amplify-codegen-e2e-core";
1+
import { addApiWithoutSchema, createNewProjectDir, generateModelIntrospection, initJSProjectWithProfile, updateApiSchema, generateModelIntrospectionWithError } from "@aws-amplify/amplify-codegen-e2e-core";
22
import { deleteAmplifyProject } from '../codegen-tests-base';
33
import { isNotEmptyDir } from "../utils";
44
import { join } from 'path';
@@ -35,7 +35,7 @@ describe('Model Introspection Codegen test', () => {
3535
await addApiWithoutSchema(projectRoot, { apiName });
3636
await updateApiSchema(projectRoot, apiName, schema);
3737
//generate introspection schema
38-
await expect(generateModelIntrospection(projectRoot)).rejects.toThrowError();
38+
await generateModelIntrospectionWithError(projectRoot, 'Expected --output-dir flag to be set');
3939
});
4040

4141
it('should throw error if the GraphQL schema is invalid', async () => {
@@ -46,7 +46,7 @@ describe('Model Introspection Codegen test', () => {
4646
await updateApiSchema(projectRoot, apiName, invalidSchema);
4747
const outputDir = 'output';
4848
//generate introspection schema
49-
await expect(generateModelIntrospection(projectRoot, { outputDir })).rejects.toThrowError();
49+
await generateModelIntrospectionWithError(projectRoot, 'Unknown type', { outputDir });
5050
});
5151

5252
it(`should handle a schema with connected PK`, async () => {

0 commit comments

Comments
 (0)