Skip to content

Commit

Permalink
chore: automatically age out old TypeScript versions from testing (#3…
Browse files Browse the repository at this point in the history
…1960)

In our integ tests, we were testing TypeScript versions from 3.9 up to the latest version, which recently broke because of a change to modernize the init templates.

We should up this range to a recent version; the common support lifetime of a TypeScript version is the one on `DefinitelyTyped`, the types registry for TypeScript packages. They only target TS versions less than 2 years old, which at the time of this PR is 4.9 and higher.

Encode that policy into code automatically, so that we don't have to manually keep this minimum version up-to-date. This currently ages out the following versions:

```
  ✕ typescript 3.9 init app
  ✕ typescript 4.0 init app
  ✕ typescript 4.1 init app
  ✕ typescript 4.2 init app
  ✕ typescript 4.3 init app
  ✕ typescript 4.4 init app
  ✕ typescript 4.5 init app
  ✕ typescript 4.6 init app
  ✕ typescript 4.7 init app
  ✕ typescript 4.8 init app
------------------------------8< cut line -----
  ✕ typescript 4.9 init app
  ✓ typescript 5.0 init app
  ✓ typescript 5.1 init app
  ✓ typescript 5.2 init app
  ✓ typescript 5.3 init app
  ✓ typescript 5.4 init app
  ✓ typescript 5.5 init app
  ✓ typescript 5.6 init app
```

Unfortunately not enough to save the TypeScript template modernization change entirely... but at least it's an improvement.

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
rix0rrr authored Oct 31, 2024
1 parent 6f106c7 commit 077262f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
30 changes: 29 additions & 1 deletion packages/@aws-cdk-testing/cli-integ/lib/npm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,32 @@ export function typescriptVersionsSync(): string[] {

const versions: string[] = JSON.parse(stdout);
return Array.from(new Set(versions.map(v => v.split('.').slice(0, 2).join('.'))));
}
}

/**
* Use NPM preinstalled on the machine to query publish times of versions
*/
export function typescriptVersionsYoungerThanDaysSync(days: number, versions: string[]): string[] {
const { stdout } = spawnSync('npm', ['--silent', 'view', 'typescript', 'time', '--json'], { encoding: 'utf-8' });
const versionTsMap: Record<string, string> = JSON.parse(stdout);

const cutoffDate = new Date(Date.now() - (days * 24 * 3600 * 1000));
const cutoffDateS = cutoffDate.toISOString();

const recentVersions = Object.entries(versionTsMap)
.filter(([_, dateS]) => dateS > cutoffDateS)
.map(([v]) => v);

// Input versions are of the form 3.9, 5.2, etc.
// Actual versions are of the form `3.9.15`, `5.3.0-dev.20511311`.
// Return only 2-digit versions for which there is a non-prerelease version in the set of recentVersions
// So a 2-digit versions that is followed by `.<digits>` until the end of the string.
return versions.filter((twoV) => {
const re = new RegExp(`^${reQuote(twoV)}\\.\\d+$`);
return recentVersions.some(fullV => fullV.match(re));
});
}

function reQuote(str: string): string {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { promises as fs } from 'fs';
import * as path from 'path';
import { integTest, withTemporaryDirectory, ShellHelper, withPackages, TemporaryDirectoryContext } from '../../lib';
import { typescriptVersionsSync } from '../../lib/npm';
import { typescriptVersionsSync, typescriptVersionsYoungerThanDaysSync } from '../../lib/npm';

['app', 'sample-app'].forEach(template => {
integTest(`typescript init ${template}`, withTemporaryDirectory(withPackages(async (context) => {
Expand All @@ -19,10 +19,18 @@ import { typescriptVersionsSync } from '../../lib/npm';
})));
});

// Same as https://github.com/DefinitelyTyped/DefinitelyTyped?tab=readme-ov-file#support-window
const TYPESCRIPT_VERSION_AGE_DAYS = 2 * 365;

const TYPESCRIPT_VERSIONS = typescriptVersionsYoungerThanDaysSync(TYPESCRIPT_VERSION_AGE_DAYS, typescriptVersionsSync());

// eslint-disable-next-line no-console
console.log(TYPESCRIPT_VERSIONS);

/**
* Test our generated code with various versions of TypeScript
*/
typescriptVersionsSync().forEach(tsVersion => {
TYPESCRIPT_VERSIONS.forEach(tsVersion => {
integTest(`typescript ${tsVersion} init app`, withTemporaryDirectory(withPackages(async (context) => {
const shell = ShellHelper.fromContext(context);
await context.packages.makeCliAvailable();
Expand Down

0 comments on commit 077262f

Please sign in to comment.