Skip to content

Commit a57c87d

Browse files
[ci] Merge branch 'main' of github.com:hyperledger-labs/splice into julien/2692-add-scan-connection-metrics
2 parents ee90561 + 4a0c074 commit a57c87d

File tree

1,413 files changed

+50449
-31768
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,413 files changed

+50449
-31768
lines changed

.github/actions/scripts/io-utils.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
# Copy stdin to stdout, while removing all lines that start with '#' or consist of blanks
1313
remove_comment_and_blank_lines() {
14-
while IFS= read -r # Read a file line by line; IFS= ensures that no separators other than newline are used
14+
while IFS= read -r || [[ -n $REPLY ]] # Read a file line by line; IFS= ensures that no separators other than newline are used
1515
do
1616
if [[ -n "${REPLY// }" ]] && [[ "$REPLY" != "#"* ]] # Filter out comment lines and blank lines
1717
then

.github/actions/tests/split_tests/dist/index.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,18 @@ function getTestSuiteTimesFromXml(testReportsDir) {
2222
try {
2323
fs_1.default.readdirSync(testReportsDir).forEach(file => {
2424
if (file.endsWith('.xml')) {
25-
const path = `${testReportsDir}/${file}`;
26-
const XMLdata = fs_1.default.readFileSync(path);
27-
const parsed = parser.parse(XMLdata);
28-
const testSuiteName = parsed.testsuite['@_name'];
29-
const testSuiteTime = parseFloat(parsed.testsuite['@_time']);
30-
testTimes[testSuiteName] = testSuiteTime;
25+
try {
26+
console.log(`Parsing xml report ${file}`);
27+
const path = `${testReportsDir}/${file}`;
28+
const XMLdata = fs_1.default.readFileSync(path);
29+
const parsed = parser.parse(XMLdata);
30+
const testSuiteName = parsed.testsuite['@_name'];
31+
const testSuiteTime = parseFloat(parsed.testsuite['@_time']);
32+
testTimes[testSuiteName] = testSuiteTime;
33+
}
34+
catch (e) {
35+
console.error(`Failed to parse xml report ${file}`);
36+
}
3137
}
3238
});
3339
}
@@ -69,7 +75,7 @@ function computeBuckets(testReportsDir, testNamesFile, splitTotal) {
6975
// Build a sorted list of test names, sorted by their estimated test time.
7076
// We first sort alphabetically, so that tests with the same estimated time
7177
// are sorted in a deterministic way.
72-
const sortedTestNames = testNames.sort().sort((a, b) => estimatedTestTimes[a] - estimatedTestTimes[b]);
78+
const sortedTestNames = testNames.sort().sort((a, b) => estimatedTestTimes[a] - estimatedTestTimes[b]).reverse();
7379
const buckets = splitTests(sortedTestNames, estimatedTestTimes, splitTotal);
7480
buckets.forEach((bucket, i) => {
7581
console.log(`bucket ${i}: ${bucket.length} tests, total time: ${bucket.reduce((acc, testName) => acc + estimatedTestTimes[testName], 0)}`);

.github/actions/tests/split_tests/src/split_tests.ts

Lines changed: 63 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,91 @@
1-
import { getInput, setFailed, setOutput } from '@actions/core';
1+
import {getInput, setFailed, setOutput} from '@actions/core';
22
import xmlParser from 'fast-xml-parser';
33
import fs from 'fs';
44

55
type TestTimes = { [name: string]: number };
66

77
function getTestSuiteTimesFromXml(testReportsDir: string): TestTimes {
88

9-
const options = {
10-
ignoreAttributes: false
11-
};
12-
const parser = new xmlParser.XMLParser(options);
13-
const testTimes: TestTimes = {};
14-
try {
15-
fs.readdirSync(testReportsDir).forEach(file => {
16-
if (file.endsWith('.xml')) {
17-
const path = `${testReportsDir}/${file}`;
18-
const XMLdata = fs.readFileSync(path);
19-
const parsed = parser.parse(XMLdata);
20-
const testSuiteName = parsed.testsuite['@_name'];
21-
const testSuiteTime = parseFloat(parsed.testsuite['@_time']);
22-
testTimes[testSuiteName] = testSuiteTime;
23-
}
24-
});
25-
} catch (err) {
26-
console.error(`Warning: could not read test reports from ${testReportsDir}: ${err}`);
27-
}
28-
29-
return testTimes;
9+
const options = {
10+
ignoreAttributes: false
11+
};
12+
const parser = new xmlParser.XMLParser(options);
13+
const testTimes: TestTimes = {};
14+
try {
15+
fs.readdirSync(testReportsDir).forEach(file => {
16+
if (file.endsWith('.xml')) {
17+
try {
18+
console.log(`Parsing xml report ${file}`)
19+
const path = `${testReportsDir}/${file}`;
20+
const XMLdata = fs.readFileSync(path);
21+
const parsed = parser.parse(XMLdata);
22+
const testSuiteName = parsed.testsuite['@_name'];
23+
const testSuiteTime = parseFloat(parsed.testsuite['@_time']);
24+
testTimes[testSuiteName] = testSuiteTime;
25+
} catch (e) {
26+
console.error(`Failed to parse xml report ${file}`)
27+
}
28+
}
29+
});
30+
} catch (err) {
31+
console.error(`Warning: could not read test reports from ${testReportsDir}: ${err}`);
32+
}
33+
34+
return testTimes;
3035
}
3136

3237
function estimateTestTimes(testTimes: TestTimes, testNames: string[]): TestTimes {
33-
let maxTestTime = Math.max(...Object.values(testTimes));
34-
// If maxTestTime is zero, i.e. no runtimes are known, we assign everything an
35-
// arbitrary non-zero value of 1.0
36-
maxTestTime = Math.max(maxTestTime, 1.0);
37-
38-
const estimatedTestTimes: TestTimes = {};
39-
testNames.forEach(testName => {
40-
estimatedTestTimes[testName] = testTimes[testName] || maxTestTime;
41-
// Scalatest actually reported occasionally test times with negative numbers,
42-
// so we set it to zero in that case.
43-
estimatedTestTimes[testName] = Math.max(estimatedTestTimes[testName], 0.0);
44-
});
45-
46-
return estimatedTestTimes
38+
let maxTestTime = Math.max(...Object.values(testTimes));
39+
// If maxTestTime is zero, i.e. no runtimes are known, we assign everything an
40+
// arbitrary non-zero value of 1.0
41+
maxTestTime = Math.max(maxTestTime, 1.0);
42+
43+
const estimatedTestTimes: TestTimes = {};
44+
testNames.forEach(testName => {
45+
estimatedTestTimes[testName] = testTimes[testName] || maxTestTime;
46+
// Scalatest actually reported occasionally test times with negative numbers,
47+
// so we set it to zero in that case.
48+
estimatedTestTimes[testName] = Math.max(estimatedTestTimes[testName], 0.0);
49+
});
50+
51+
return estimatedTestTimes
4752
}
4853

4954
function splitTests(sortedTestNames: string[], estimatedTestTimes: TestTimes, splitTotal: number): string[][] {
50-
const bucketTimes = Array(splitTotal).fill(0);
51-
const buckets = Array.from(Array(splitTotal), () => new Array())
55+
const bucketTimes = Array(splitTotal).fill(0);
56+
const buckets = Array.from(Array(splitTotal), () => new Array())
5257

5358

54-
sortedTestNames.forEach(testName => {
55-
const minBucketIndex = bucketTimes.indexOf(Math.min(...bucketTimes));
56-
bucketTimes[minBucketIndex] += estimatedTestTimes[testName];
57-
buckets[minBucketIndex].push(testName);
59+
sortedTestNames.forEach(testName => {
60+
const minBucketIndex = bucketTimes.indexOf(Math.min(...bucketTimes));
61+
bucketTimes[minBucketIndex] += estimatedTestTimes[testName];
62+
buckets[minBucketIndex].push(testName);
5863

59-
console.log(`added ${testName} to bucket ${minBucketIndex}, total time: ${bucketTimes[minBucketIndex]}`);
60-
console.log(`bucket ${minBucketIndex} has ${buckets[minBucketIndex].length} tests`);
61-
});
64+
console.log(`added ${testName} to bucket ${minBucketIndex}, total time: ${bucketTimes[minBucketIndex]}`);
65+
console.log(`bucket ${minBucketIndex} has ${buckets[minBucketIndex].length} tests`);
66+
});
6267

63-
return buckets;
68+
return buckets;
6469
}
6570

6671
function computeBuckets(testReportsDir: string, testNamesFile: string, splitTotal: number) {
67-
const testTimes = getTestSuiteTimesFromXml(testReportsDir);
72+
const testTimes = getTestSuiteTimesFromXml(testReportsDir);
6873

69-
const testNames = fs.readFileSync(testNamesFile).toString().split('\n').filter(name => name.length > 0);
74+
const testNames = fs.readFileSync(testNamesFile).toString().split('\n').filter(name => name.length > 0);
7075

71-
const estimatedTestTimes = estimateTestTimes(testTimes, testNames);
76+
const estimatedTestTimes = estimateTestTimes(testTimes, testNames);
7277

73-
// Build a sorted list of test names, sorted by their estimated test time.
74-
// We first sort alphabetically, so that tests with the same estimated time
75-
// are sorted in a deterministic way.
76-
const sortedTestNames = testNames.sort().sort((a, b) => estimatedTestTimes[a] - estimatedTestTimes[b]);
78+
// Build a sorted list of test names, sorted by their estimated test time.
79+
// We first sort alphabetically, so that tests with the same estimated time
80+
// are sorted in a deterministic way.
81+
const sortedTestNames = testNames.sort().sort((a, b) => estimatedTestTimes[a] - estimatedTestTimes[b]).reverse();
7782

78-
const buckets = splitTests(sortedTestNames, estimatedTestTimes, splitTotal);
83+
const buckets = splitTests(sortedTestNames, estimatedTestTimes, splitTotal);
7984

80-
buckets.forEach((bucket, i) => {
81-
console.log(`bucket ${i}: ${bucket.length} tests, total time: ${bucket.reduce((acc, testName) => acc + estimatedTestTimes[testName], 0)}`);
82-
});
83-
return buckets;
85+
buckets.forEach((bucket, i) => {
86+
console.log(`bucket ${i}: ${bucket.length} tests, total time: ${bucket.reduce((acc, testName) => acc + estimatedTestTimes[testName], 0)}`);
87+
});
88+
return buckets;
8489
}
8590

8691
const buckets = computeBuckets(getInput('test_reports_dir'), getInput('test_names_file'), parseInt(getInput('split_total')));

.github/workflows/build.scala_test.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ on:
6262
jobs:
6363

6464
split_tests:
65-
runs-on: ubuntu-24.04
65+
# required to have access to the /cache directory to read test-reports
66+
runs-on: self-hosted-k8s-small
67+
container:
68+
image: us-central1-docker.pkg.dev/da-cn-shared/ghcr/digital-asset/decentralized-canton-sync-dev/docker/splice-test-ci:0.3.12
6669
name: Split the tests into parallel runs
6770
outputs:
6871
indices: ${{ steps.prep.outputs.indices }}

.github/workflows/build.scala_test_for_compose.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ on:
3333
jobs:
3434

3535
split_tests:
36-
runs-on: ubuntu-24.04
36+
# required to have access to the /cache directory to read test-reports
37+
runs-on: self-hosted-k8s-small
38+
container:
39+
image: us-central1-docker.pkg.dev/da-cn-shared/ghcr/digital-asset/decentralized-canton-sync-dev/docker/splice-test-ci:0.3.12
3740
name: Split the tests into parallel runs
3841
outputs:
3942
indices: ${{ steps.prep.outputs.indices }}

.github/workflows/build.scala_test_with_cometbft.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ on:
2525
jobs:
2626

2727
split_tests:
28-
runs-on: ubuntu-24.04
28+
# required to have access to the /cache directory to read test-reports
29+
runs-on: self-hosted-k8s-small
30+
container:
31+
image: us-central1-docker.pkg.dev/da-cn-shared/ghcr/digital-asset/decentralized-canton-sync-dev/docker/splice-test-ci:0.3.12
2932
name: Split the tests into parallel runs
3033
outputs:
3134
indices: ${{ steps.prep.outputs.indices }}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Bump GHA runner version
2+
on:
3+
schedule:
4+
- cron: '30 6 1,15 * *' # Monthly on the 1st and 15th at 06:30
5+
workflow_dispatch:
6+
7+
jobs:
8+
bump_gha_runner_version:
9+
name: Bump GHA runner version
10+
runs-on: self-hosted-k8s-small
11+
container:
12+
image: us-central1-docker.pkg.dev/da-cn-shared/ghcr/digital-asset/decentralized-canton-sync-dev/docker/splice-test-ci:0.3.12
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
16+
17+
- name: Setup
18+
shell: bash
19+
run: ./.github/actions/scripts/common_setup.sh
20+
21+
- name: Set up Nix (Self hosted)
22+
uses: ./.github/actions/nix/setup_nix
23+
with:
24+
cache_version: 7
25+
artifactory_user: dummy
26+
artifactory_password: dummy
27+
28+
- name: Check for the latest version and create a PR to splice
29+
uses: ./.github/actions/nix/run_bash_command_in_nix
30+
with:
31+
cmd: |
32+
git config user.email "splice-maintainers@digitalasset.com"
33+
git config user.name "DA Automation"
34+
./scripts/bump-gha-runner-version.sh
35+
additional_nix_args: "--keep GH_TOKEN"
36+
env:
37+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38+
39+
- name: Report Failures on Slack & Github
40+
if: failure() && (github.event_name == 'push' || github.event_name == 'schedule')
41+
uses: ./.github/actions/tests/failure_notifications
42+
with:
43+
workload_identity_provider: '${{ secrets.GOOGLE_WORKLOAD_IDENTITY_PROVIDER }}'
44+
service_account: '${{ secrets.FAILURE_NOTIFICATIONS_INVOKER_SA }}'
45+
notifications_url: '${{ secrets.FAILURE_NOTIFICATIONS_INVOKER_URL }}'
46+
slack_channel: '${{ secrets.FAILURE_NOTIFICATIONS_SLACK_CHANNEL }}'

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.daml
22
*.dar
33
!daml/dars/*
4+
*.iml
45
*.log
56
*.clog
67
.DS_Store

.pre-commit-config.yaml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ repos:
5050
language: system
5151
entry: "scripts/fix-ts.py"
5252
types_or: [javascript, jsx, ts, tsx]
53-
exclude: "/[.]prettierrc[.]cjs$"
54-
- id: pulumi_config
55-
name: check pulumi configs
53+
# TODO(#3334): The current implementation of fix-ts.py makes it impossible to format files
54+
# in the top level pulumi package.
55+
exclude: "(/[.]prettierrc[.]cjs$|/pulumi/[^/]+.ts$)"
56+
- id: pulumi_tests
57+
name: run pulumi tests and check expected files
5658
language: system
5759
entry: "make cluster/pulumi/test -j8"
58-
files: '^cluster/pulumi/.*[.]ts$'
60+
files: '^(cluster/pulumi/.*[.]ts|cluster/.*[.](yaml|yml))$'
5961
pass_filenames: false
6062
- id: gha_lint
6163
name: static check github actions

.scalafmt.conf

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@ newlines.topLevelStatementBlankLines = [
1212
{ blanks { after = 1 }, regex = "^Import" }
1313
]
1414

15-
rewrite.scala3.convertToNewSyntax= true
15+
rewrite.scala3.convertToNewSyntax = true
1616

1717
runner.dialect = "scala213source3"
18-
runner.dialectOverride.allowQuestionMarkAsTypeWildcard = false
1918
runner.dialectOverride.allowUnderscoreAsTypePlaceholder = false
2019

2120
fileOverride {

0 commit comments

Comments
 (0)