Skip to content

Commit

Permalink
Merge branch 'main' into otaviom/renaming-warning
Browse files Browse the repository at this point in the history
  • Loading branch information
otaviomacedo committed Jan 31, 2025
2 parents d52a25b + c346e82 commit 7e3e263
Show file tree
Hide file tree
Showing 1,794 changed files with 357,259 additions and 198,584 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
steps:
- name: 'Download workflow_run artifact'
if: github.event_name == 'workflow_run'
uses: dawidd6/action-download-artifact@v7
uses: dawidd6/action-download-artifact@v8
with:
run_id: ${{ github.event.workflow_run.id }}
name: pr_info
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/project-prioritization-bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: P1 Bug Prioritization
on:
issues:
types:
- labeled

jobs:
prioritize:
if: github.repository == 'aws/aws-cdk' && contains(github.event.issue.labels.*.name, 'bug') && contains(github.event.issue.labels.*.name, 'p1')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Add P1 Bug to project
uses: actions/github-script@v7
with:
github-token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
script: |
const script = require('./scripts/prioritization/assign-bug-priority.js')
await script({github, context})
39 changes: 31 additions & 8 deletions packages/@aws-cdk-testing/cli-integ/lib/aws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@ import {
import { SNSClient } from '@aws-sdk/client-sns';
import { SSOClient } from '@aws-sdk/client-sso';
import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
import { fromIni } from '@aws-sdk/credential-providers';
import type { AwsCredentialIdentityProvider } from '@smithy/types';
import { fromIni, fromNodeProviderChain } from '@aws-sdk/credential-providers';
import type { AwsCredentialIdentity, AwsCredentialIdentityProvider } from '@smithy/types';
import { ConfiguredRetryStrategy } from '@smithy/util-retry';
interface ClientConfig {
readonly credentials?: AwsCredentialIdentityProvider;
readonly credentials: AwsCredentialIdentityProvider | AwsCredentialIdentity;
readonly region: string;
readonly retryStrategy: ConfiguredRetryStrategy;
}

export class AwsClients {
public static async forIdentity(region: string, identity: AwsCredentialIdentity, output: NodeJS.WritableStream) {
return new AwsClients(region, output, identity);
}

public static async forRegion(region: string, output: NodeJS.WritableStream) {
return new AwsClients(region, output);
}
Expand All @@ -45,9 +49,12 @@ export class AwsClients {
public readonly lambda: LambdaClient;
public readonly sts: STSClient;

constructor(public readonly region: string, private readonly output: NodeJS.WritableStream) {
constructor(
public readonly region: string,
private readonly output: NodeJS.WritableStream,
public readonly identity?: AwsCredentialIdentity) {
this.config = {
credentials: chainableCredentials(this.region),
credentials: this.identity ?? chainableCredentials(this.region),
region: this.region,
retryStrategy: new ConfiguredRetryStrategy(9, (attempt: number) => attempt ** 500),
};
Expand All @@ -73,6 +80,17 @@ export class AwsClients {
return (await stsClient.send(new GetCallerIdentityCommand({}))).Account!;
}

/**
* Resolve the current identity or identity provider to credentials
*/
public async credentials() {
const x = this.config.credentials;
if (isAwsCredentialIdentity(x)) {
return x;
}
return x();
}

public async deleteStacks(...stackNames: string[]) {
if (stackNames.length === 0) {
return;
Expand Down Expand Up @@ -244,8 +262,8 @@ export async function sleep(ms: number) {
return new Promise((ok) => setTimeout(ok, ms));
}

function chainableCredentials(region: string): AwsCredentialIdentityProvider | undefined {
if (process.env.CODEBUILD_BUILD_ARN && process.env.AWS_PROFILE) {
function chainableCredentials(region: string): AwsCredentialIdentityProvider {
if ((process.env.CODEBUILD_BUILD_ARN || process.env.GITHUB_RUN_ID) && process.env.AWS_PROFILE) {
// in codebuild we must assume the role that the cdk uses
// otherwise credentials will just be picked up by the normal sdk
// heuristics and expire after an hour.
Expand All @@ -254,5 +272,10 @@ function chainableCredentials(region: string): AwsCredentialIdentityProvider | u
});
}

return undefined;
// Otherwise just get what's default
return fromNodeProviderChain({ clientConfig: { region } });
}

function isAwsCredentialIdentity(x: any): x is AwsCredentialIdentity {
return Boolean(x && typeof x === 'object' && x.accessKeyId);
}
2 changes: 1 addition & 1 deletion packages/@aws-cdk-testing/cli-integ/lib/cli/run-suite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ async function main() {

try {
await jest.run([
'--randomize',
...args.runInBand ? ['-i'] : [],
...args.test ? ['-t', args.test] : [],
...args.verbose ? ['--verbose'] : [],
...passWithNoTests ? ['--passWithNoTests'] : [],
...args['test-file'] ? [args['test-file']] : [],
], path.resolve(__dirname, '..', '..', 'resources', 'integ.jest.config.js'));

} finally {
await packageSource.cleanup();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ async function main() {
type: 'string',
requiresArg: true,
}), async (args) => {

await validateDirectory(args);
const repo = await (args.name ? TestRepository.newWithName(args.name) : TestRepository.newRandom());
const usageDir = UsageDir.default();
Expand All @@ -71,7 +70,6 @@ async function main() {
requiresArg: true,
demandOption: true,
}), async (args) => {

const repo = TestRepository.existing(args.name);
const usageDir = UsageDir.default();

Expand Down Expand Up @@ -99,7 +97,6 @@ async function main() {
default: true,
requiresArg: false,
}), async (args) => {

await validateDirectory(args);
const repo = await TestRepository.newRandom();
const usageDir = UsageDir.default();
Expand All @@ -114,7 +111,6 @@ async function main() {
shell: true,
show: 'always',
});

} finally {
if (args.cleanup) {
await repo.delete();
Expand All @@ -128,7 +124,6 @@ async function main() {
type: 'string',
requiresArg: true,
}), async (args) => {

const usageDir = UsageDir.default();

let repositoryName = args.name;
Expand Down
2 changes: 1 addition & 1 deletion packages/@aws-cdk-testing/cli-integ/lib/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ export async function fetchPreviousVersion(token: string, options?: {
if (previousMVRelease) { return previousMVRelease; }

throw new Error(`Unable to find previous version given ${JSON.stringify(options)}`);
};
}
52 changes: 46 additions & 6 deletions packages/@aws-cdk-testing/cli-integ/lib/integ-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ if (SKIP_TESTS) {
process.stderr.write(`ℹ️ Skipping tests: ${JSON.stringify(SKIP_TESTS)}\n`);
}

// Whether we want to stop after the first failure, for quicker debugging (hopefully).
const FAIL_FAST = process.env.FAIL_FAST === 'true';

// Keep track of whether the suite has failed. If so, we stop running.
let failed = false;

export interface TestContext {
readonly randomString: string;
readonly name: string;
readonly output: NodeJS.WritableStream;
log(s: string): void;
};
}

if (process.env.JEST_TEST_CONCURRENT === 'true') {
process.stderr.write('ℹ️ JEST_TEST_CONCURRENT is true: tests will run concurrently and filters have no effect!\n0');
Expand Down Expand Up @@ -48,21 +55,54 @@ export function integTest(
const now = Date.now();
process.stderr.write(`[INTEG TEST::${name}] Starting (pid ${process.pid})...\n`);
try {
if (FAIL_FAST && failed) {
throw new Error('FAIL_FAST requested and currently failing. Stopping test early.');
}

return await callback({
output,
randomString: randomString(),
name,
log(s: string) {
output.write(`${s}\n`);
},
});
} catch (e: any) {
process.stderr.write(`[INTEG TEST::${name}] Failed: ${e}\n`);
failed = true;

// Print the buffered output, only if the test fails.
output.write(e.message);
output.write(e.stack);
// Print output only if the test fails. Use 'console.log' so the output is buffered by
// jest and prints without a stack trace (if verbose: false).
// eslint-disable-next-line no-console
console.log(output.buffer().toString());
process.stderr.write(`[INTEG TEST::${name}] Failed: ${e}\n`);

const isGitHub = !!process.env.GITHUB_RUN_ID;

if (isGitHub) {
// GitHub Actions compatible output formatting
// https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#setting-an-error-message
let written = process.stderr.write(`::error title=Failed ${name}::${e.message}\n`);
if (!written) {
// Wait for drain
await new Promise((ok) => process.stderr.once('drain', ok));
}

// Print output only if the test fails. Use 'console.log' so the output is buffered by
// jest and prints without a stack trace (if verbose: false).
written = process.stdout.write([
`::group::Failure details: ${name} (click to expand)\n`,
`${output.buffer().toString()}\n`,
'::endgroup::\n',
].join(''));
if (!written) {
// Wait for drain
await new Promise((ok) => process.stdout.once('drain', ok));
}
} else {
// Use 'console.log' so the output is buffered by
// jest and prints without a stack trace (if verbose: false).
// eslint-disable-next-line no-console
console.log(output.buffer().toString());
}
throw e;
} finally {
const duration = Date.now() - now;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { shell, rimraf, addToShellPath } from '../shell';

export class ReleasePackageSourceSetup implements IPackageSourceSetup {
readonly name = 'release';
readonly description = `release @ ${this.version}`;
readonly description: string;

private tempDir?: string;

constructor(private readonly version: string, private readonly frameworkVersion?: string) {
this.description = `release @ ${this.version}`;
}

public async prepare(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { shell, addToShellPath } from '../shell';

export class RepoPackageSourceSetup implements IPackageSourceSetup {
readonly name = 'repo';
readonly description = `repo(${this.repoRoot})`;
readonly description: string;

constructor(private readonly repoRoot: string) {
this.description = `repo(${this.repoRoot})`;
}

public async prepare(): Promise<void> {
Expand Down Expand Up @@ -75,10 +76,10 @@ async function writePackageMap(repoRoot: string): Promise<string> {
const YARN_MONOREPO_CACHE: Record<string, any> = {};

/**
* Return a { name -> directory } packages found in a Yarn monorepo
*
* Cached in YARN_MONOREPO_CACHE.
*/
* Return a { name -> directory } packages found in a Yarn monorepo
*
* Cached in YARN_MONOREPO_CACHE.
*/
export async function findYarnPackages(root: string): Promise<Record<string, string>> {
if (!(root in YARN_MONOREPO_CACHE)) {
const outputDataString: string = JSON.parse(await shell(['yarn', 'workspaces', '--json', 'info'], {
Expand Down
64 changes: 64 additions & 0 deletions packages/@aws-cdk-testing/cli-integ/lib/proxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { promises as fs } from 'fs';
import * as querystring from 'node:querystring';
import * as os from 'os';
import * as path from 'path';
import * as mockttp from 'mockttp';
import { CompletedRequest } from 'mockttp';

export async function startProxyServer(certDirRoot?: string): Promise<ProxyServer> {
const certDir = await fs.mkdtemp(path.join(certDirRoot ?? os.tmpdir(), 'cdk-'));
const certPath = path.join(certDir, 'cert.pem');
const keyPath = path.join(certDir, 'key.pem');

// Set up key and certificate
const { key, cert } = await mockttp.generateCACertificate();
await fs.writeFile(keyPath, key);
await fs.writeFile(certPath, cert);

const server = mockttp.getLocal({
https: { keyPath: keyPath, certPath: certPath },
});

// We don't need to modify any request, so the proxy
// passes through all requests to the target host.
const endpoint = await server
.forAnyRequest()
.thenPassThrough();

const port = 9000 + Math.floor(Math.random() * 10000);

// server.enableDebug();
await server.start(port);

return {
certPath,
keyPath,
server,
url: server.url,
port: server.port,
getSeenRequests: () => endpoint.getSeenRequests(),
async stop() {
await server.stop();
await fs.rm(certDir, { recursive: true, force: true });
},
};
}

export interface ProxyServer {
readonly certPath: string;
readonly keyPath: string;
readonly server: mockttp.Mockttp;
readonly url: string;
readonly port: number;

getSeenRequests(): Promise<CompletedRequest[]>;
stop(): Promise<void>;
}

export function awsActionsFromRequests(requests: CompletedRequest[]): string[] {
return [...new Set(requests
.map(req => req.body.buffer.toString('utf-8'))
.map(body => querystring.decode(body))
.map(x => x.Action as string)
.filter(action => action != null))];
}
Loading

0 comments on commit 7e3e263

Please sign in to comment.