Skip to content

build

build #4819

Workflow file for this run

# ~~ Generated by projen. To modify, edit .projenrc.ts and run "npx projen".
name: build
on:
merge_group: {}
pull_request: {}
push:
branches:
- main
- maintenance/*
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
self-mutation-needed: ${{ steps.self-mutation.outputs.needed }}
release-line: ${{ steps.version.outputs.release-line }}
env:
CI: "true"
steps:
- name: Checkout
uses: actions/checkout@v3
with:
repository: ${{ github.repository }}
lfs: true
ref: ${{ github.ref }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
cache: yarn
- name: Cache build outputs
if: github.event_name == 'pull_request'
uses: actions/cache@v3
with:
key: build-outputs-${{ hashFiles('tsconfig.json', 'build-tools/**/*.ts', 'src/**/*.ts', 'package.json', 'yarn.lock') }}
path: |-
tsconfig.tsbuildinfo
lib/**/*
restore-keys: build-outputs-
- name: Install dependencies
run: yarn install --check-files
- name: Compile
run: npx projen && npx projen pre-compile && npx projen compile && npx projen post-compile
- name: Test
run: npx projen test
- name: Find mutations
id: self-mutation
run: |-
git add .
git diff --cached --patch --exit-code > .repo.patch || echo "needed=true" >> $GITHUB_OUTPUT
- name: Upload patch
if: steps.self-mutation.outputs.needed
uses: actions/[email protected]
with:
name: .repo.patch
path: .repo.patch
overwrite: true
- name: Fail if self-mutation is needed
if: steps.self-mutation.outputs.needed
run: |-
echo "::error::Files were changed during build (see build log). If this was triggered from a fork, you will need to update your branch."
cat .repo.patch
exit 1
- name: Upload artifact
uses: actions/[email protected]
with:
name: build-output
path: |-
${{ github.workspace }}
${{ github.workspace }}/dist/private
!${{ github.workspace }}/node_modules
!${{ github.workspace }}/fixtures/node_modules
overwrite: true
- name: Version Line
id: version
run: |-
VERSION=$(node -p "require('./lib/version.js').RELEASE_LINE")
echo "release-line=${VERSION}" >> $GITHUB_OUTPUT
self-mutation:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
env:
CI: "true"
if: always() && (github.event_name == 'pull_request') && needs.build.outputs.self-mutation-needed && (github.event.pull_request.head.repo.full_name == github.repository)
steps:
- name: Checkout
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
token: ${{ secrets.PROJEN_GITHUB_TOKEN }}
- name: Download patch
uses: actions/download-artifact@v4
with:
name: .repo.patch
path: ${{ runner.temp }}
- name: Apply patch
run: '[ -s ${{ runner.temp }}/.repo.patch ] && git apply ${{ runner.temp }}/.repo.patch || echo "Empty patch. Skipping."'
- name: Set git identity
run: |-
git config user.name "github-actions"
git config user.email "[email protected]"
- name: Push changes
run: |-
git add .
git commit -s -m "chore: self-mutation"
git push origin HEAD:${{ github.event.pull_request.head.ref }}
matrix-test:
name: test (node ${{ matrix.node-version }})
needs: build
runs-on: ubuntu-latest
permissions: {}
env:
CI: "true"
if: success()
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: build-output
path: ${{ github.workspace }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: yarn
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Re-run post-compile
run: npx projen post-compile
- name: Test
run: npx projen test
- name: Assert clean working directory
run: git diff --cached --exit-code
strategy:
fail-fast: false
matrix:
node-version:
- 18.x
- 20.x
- 22.x
matrix-clear:
name: Unit Tests
needs: matrix-test
runs-on: ubuntu-latest
permissions: {}
env:
CI: "true"
if: always()
steps:
- name: Build result
run: echo ${{needs.matrix-test.result}}
- name: Set status based on matrix build
if: ${{ needs.matrix-test.result != 'success' }}
run: exit 1
package:
name: package
needs: build
runs-on: ubuntu-latest
permissions: {}
env:
CI: "true"
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: build-output
path: ${{ github.workspace }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "18"
cache: yarn
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Package
run: npx projen package
- name: Upload artifact
uses: actions/[email protected]
with:
name: release-package
path: ${{ github.workspace }}/dist
overwrite: true
install-test:
name: Install Test (${{ matrix.runs-on }} | node ${{ matrix.node-version }} | ${{ matrix.package-manager }})
needs: package
runs-on: ${{ matrix.runs-on }}
permissions: {}
env:
CI: "true"
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: release-package
path: ${{ runner.temp }}/release-package
- name: Install from tarball (npm)
if: runner.os != 'Windows' && matrix.package-manager == 'npm'
run: |-
npm init -y
npm install ${{ runner.temp }}/release-package/js/jsii-*.tgz
- name: Install from tarball (yarn)
if: runner.os != 'Windows' && matrix.package-manager == 'yarn'
run: |-
yarn init -y
yarn add ${{ runner.temp }}/release-package/js/jsii-*.tgz
- name: Install from tarball (Windows, npm)
if: runner.os == 'Windows' && matrix.package-manager == 'npm'
run: |-
npm init -y
$TARBALL = Get-ChildItem -Path "${{ runner.temp }}/release-package/js/jsii-*.tgz"
npm install $TARBALL
- name: Install from tarball (Windows, yarn)
if: runner.os == 'Windows' && matrix.package-manager == 'yarn'
run: |-
yarn init -y
$TARBALL = Get-ChildItem -Path "${{ runner.temp }}/release-package/js/jsii-*.tgz"
yarn add $TARBALL
- name: Simple command
run: ./node_modules/.bin/jsii --version
strategy:
fail-fast: false
matrix:
node-version:
- 18.x
- 20.x
- 22.x
package-manager:
- npm
- yarn
runs-on:
- ubuntu-latest
- windows-latest
- macos-latest
pacmak-test:
name: Pacmak Test
needs: package
runs-on: ubuntu-latest
permissions: {}
env:
CI: "true"
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with: {}
- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: release-package
path: ${{ runner.temp }}/release-package
- name: Install from tarball
run: |-
npm init -y
npm install [email protected] ${{ runner.temp }}/release-package/private/*.tgz
npm ls --depth=0
./node_modules/.bin/jsii-pacmak --version
- name: Run jsii-pacmak
run: ./node_modules/.bin/jsii-pacmak --verbose --recurse ./node_modules/jsii-calc
integ-clear:
name: Integration Tests
needs:
- install-test
- pacmak-test
runs-on: ubuntu-latest
permissions: {}
env:
CI: "true"
steps:
- name: Done
run: echo OK
benchmark:
name: Benchmark (${{ matrix.compiler }}, run ${{ matrix.index }})
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
jsii-0: ${{ steps.run.outputs.jsii-0 }}
tsc-0: ${{ steps.run.outputs.tsc-0 }}
jsii-1: ${{ steps.run.outputs.jsii-1 }}
tsc-1: ${{ steps.run.outputs.tsc-1 }}
jsii-2: ${{ steps.run.outputs.jsii-2 }}
tsc-2: ${{ steps.run.outputs.tsc-2 }}
jsii-3: ${{ steps.run.outputs.jsii-3 }}
tsc-3: ${{ steps.run.outputs.tsc-3 }}
jsii-4: ${{ steps.run.outputs.jsii-4 }}
tsc-4: ${{ steps.run.outputs.tsc-4 }}
jsii-5: ${{ steps.run.outputs.jsii-5 }}
tsc-5: ${{ steps.run.outputs.tsc-5 }}
jsii-6: ${{ steps.run.outputs.jsii-6 }}
tsc-6: ${{ steps.run.outputs.tsc-6 }}
jsii-7: ${{ steps.run.outputs.jsii-7 }}
tsc-7: ${{ steps.run.outputs.tsc-7 }}
jsii-8: ${{ steps.run.outputs.jsii-8 }}
tsc-8: ${{ steps.run.outputs.tsc-8 }}
jsii-9: ${{ steps.run.outputs.jsii-9 }}
tsc-9: ${{ steps.run.outputs.tsc-9 }}
jsii-10: ${{ steps.run.outputs.jsii-10 }}
tsc-10: ${{ steps.run.outputs.tsc-10 }}
jsii-11: ${{ steps.run.outputs.jsii-11 }}
tsc-11: ${{ steps.run.outputs.tsc-11 }}
jsii-12: ${{ steps.run.outputs.jsii-12 }}
tsc-12: ${{ steps.run.outputs.tsc-12 }}
jsii-13: ${{ steps.run.outputs.jsii-13 }}
tsc-13: ${{ steps.run.outputs.tsc-13 }}
jsii-14: ${{ steps.run.outputs.jsii-14 }}
tsc-14: ${{ steps.run.outputs.tsc-14 }}
jsii-15: ${{ steps.run.outputs.jsii-15 }}
tsc-15: ${{ steps.run.outputs.tsc-15 }}
jsii-16: ${{ steps.run.outputs.jsii-16 }}
tsc-16: ${{ steps.run.outputs.tsc-16 }}
jsii-17: ${{ steps.run.outputs.jsii-17 }}
tsc-17: ${{ steps.run.outputs.tsc-17 }}
jsii-18: ${{ steps.run.outputs.jsii-18 }}
tsc-18: ${{ steps.run.outputs.tsc-18 }}
jsii-19: ${{ steps.run.outputs.jsii-19 }}
tsc-19: ${{ steps.run.outputs.tsc-19 }}
env:
CI: "true"
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with: {}
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: build-output
- name: Install dependencies
run: yarn install --check-files
- name: Benchmark
id: run
run: |-
set -x
RESULT=$(yarn --silent projen test:benchmark --compiler=${{ matrix.compiler }})
echo "${{ matrix.compiler }}-${{ matrix.index }}=${RESULT}" >> $GITHUB_OUTPUT
strategy:
matrix:
compiler:
- jsii
- tsc
index:
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
benchmark_summary:
name: Benchmark
needs:
- benchmark
- build
runs-on: ubuntu-latest
permissions:
id-token: write
env:
CI: "true"
steps:
- name: Output Summary
id: output_summary
run: |-
node <<"EOF"
const fs = require("node:fs");
const outputFilePath = process.env.GITHUB_OUTPUT;
const results = ${{ toJSON(needs.benchmark.outputs) }};
console.debug(results);
const stats = {};
for (const [key, value] of Object.entries(results)) {
const [compiler,] = key.split("-");
stats[compiler] ??= [];
stats[compiler].push(JSON.parse(value).time);
}
for (const [compiler, values] of Object.entries(stats)) {
const avg = values.reduce((a, b) => a + b, 0) / values.length;
const variance = values.reduce((vari, elt) => ((elt - avg) ** 2) + vari, 0) / values.length;
stats[compiler] = {
min: Math.min(...values),
max: Math.max(...values),
avg,
stddev: Math.sqrt(variance),
};
}
const fastest = Object.values(stats).reduce((fast, { avg }) => Math.min(fast, avg), Infinity);
const summary = [
"## Benchmark Results",
"",
"Compiler | Fastest | Avergae | Slowest | StdDev | Slowdown",
"---------|--------:|--------:|--------:|-------:|--------:",
];
const ms = new Intl.NumberFormat("en-US", { style: "unit", unit: "millisecond", maximumFractionDigits: 1, minimumFractionDigits: 1 });
const dec = new Intl.NumberFormat("en-US", { style: "decimal", maximumFractionDigits: 1, minimumFractionDigits: 1 });
const pre = (s) => `\`${s}\``;
for (const [compiler, { min, max, avg, stddev }] of Object.entries(stats).sort(([, l], [, r]) => l.avg - r.avg)) {
summary.push([compiler, pre(ms.format(min)), pre(ms.format(avg)), pre(ms.format(max)), pre(dec.format(stddev)), pre(`${dec.format(avg / fastest)}x`)].join(" | "));
const key = 'duration-' + compiler;
const value = avg;
const slowdownKey = compiler + '-slowdown';
const slowdownValue = dec.format(avg / fastest);
fs.appendFileSync(outputFilePath, `${key}=${value}
`)
fs.appendFileSync(outputFilePath, `${slowdownKey}=${slowdownValue}
`)
}
summary.push("");
fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary.join("\n"), "utf-8");
EOF
- name: Authenticate Via OIDC Role
if: github.event.repository.fork == false && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/maintenance/v'))
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: us-east-1
role-duration-seconds: 900
role-to-assume: arn:aws:iam::590183883712:role/Ops-jsiiTeamOIDC-Role1ABCC5F0-jL37v7e7I15P
role-session-name: github-diff-action@cdk-ops
output-credentials: true
- name: Publish Metrics
if: github.event.repository.fork == false && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/maintenance/v'))
run: |-
aws cloudwatch put-metric-data --namespace JsiiPerformance --metric-data '[
{
"MetricName": "TSC-average",
"Value": ${{steps.output_summary.outputs.duration-tsc}}
},
{
"MetricName": "JSII-average",
"Value": ${{steps.output_summary.outputs.duration-jsii}}
},
{
"MetricName": "JSII-slowdown",
"Value": ${{steps.output_summary.outputs.jsii-slowdown}}
},
{
"MetricName": "TSC-average",
"Value": ${{steps.output_summary.outputs.duration-tsc}},
"Dimensions": [
{
"Name": "TscVersion",
"Value": "${{ needs.build.outputs.release-line }}"
}
]
},
{
"MetricName": "JSII-average",
"Value": ${{steps.output_summary.outputs.duration-jsii}},
"Dimensions": [
{
"Name": "JsiiVersion",
"Value": "${{ needs.build.outputs.release-line }}"
}
]
},
{
"MetricName": "JSII-slowdown",
"Value": ${{steps.output_summary.outputs.jsii-slowdown}},
"Dimensions": [
{
"Name": "JsiiVersion",
"Value": "${{ needs.build.outputs.release-line }}"
}
]
}
]'