Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
pull_request:
# The branches below must be a subset of the branches above
branches: [ 'develop' ]
paths-ignore: [ '**/*.md', '.gitignore', '**/.gitignore', '.editorconfig',
'.gitattributes', 'docs/**', 'CHANGELOG', '.github/ISSUE_TEMPLATE/**',
'.github/PULL_REQUEST_TEMPLATE/**', '.github/CODEOWNERS' ]
schedule:
- cron: '6 10 * * 0'

Expand All @@ -29,16 +32,23 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@v5

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: manual

- name: Autobuild
uses: github/codeql-action/autobuild@v4
- name: Set up JDK 8
uses: actions/setup-java@v5
with:
java-version: '8'
distribution: 'temurin'

- name: Build
run: ./gradlew build -x test --no-daemon

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
Expand Down
58 changes: 58 additions & 0 deletions .github/workflows/coverage-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Coverage Build

on:
pull_request:
branches: [ 'develop', 'release_**' ]
types: [ opened, synchronize, reopened ]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
build-coverage:
name: Build ubuntu24 (JDK 8 / x86_64)
runs-on: ubuntu-24.04
timeout-minutes: 60

steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Set up JDK 8
uses: actions/setup-java@v5
with:
java-version: '8'
distribution: 'temurin'
cache: 'gradle'

- name: Check Java version
run: java -version

- name: Stop Gradle daemon
run: ./gradlew --stop || true

- name: Build
run: ./gradlew clean build --no-daemon --no-build-cache --parallel

- name: Generate JaCoCo report
run: ./gradlew jacocoTestReport --no-daemon --no-build-cache

- name: Upload JaCoCo artifact
uses: actions/upload-artifact@v6
with:
name: jacoco-coverage
path: |
actuator/build/reports/jacoco/test/jacocoTestReport.xml
chainbase/build/reports/jacoco/test/jacocoTestReport.xml
common/build/reports/jacoco/test/jacocoTestReport.xml
consensus/build/reports/jacoco/test/jacocoTestReport.xml
crypto/build/reports/jacoco/test/jacocoTestReport.xml
framework/build/reports/jacoco/test/jacocoTestReport.xml
plugins/build/reports/jacoco/test/jacocoTestReport.xml
if-no-files-found: error
92 changes: 92 additions & 0 deletions .github/workflows/coverage-update-baseline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Base Coverage Upload

on:
push:
branches: [ 'develop', 'release_**' ]

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build-base-coverage:
name: Build Base Coverage
runs-on: ubuntu-24.04
timeout-minutes: 60

steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Set up JDK 8
uses: actions/setup-java@v5
with:
java-version: '8'
distribution: 'temurin'
cache: 'gradle'

- name: Check Java version
run: java -version

- name: Grant execute permission
run: chmod +x gradlew

- name: Stop Gradle daemon
run: ./gradlew --stop || true

- name: Build
run: ./gradlew clean build --no-daemon --no-build-cache --parallel

- name: Generate JaCoCo report
run: ./gradlew jacocoTestReport --no-daemon --no-build-cache

- name: Upload coverage artifacts
uses: actions/upload-artifact@v6
with:
name: base-jacoco-xml
path: |
actuator/build/reports/jacoco/test/jacocoTestReport.xml
chainbase/build/reports/jacoco/test/jacocoTestReport.xml
common/build/reports/jacoco/test/jacocoTestReport.xml
consensus/build/reports/jacoco/test/jacocoTestReport.xml
crypto/build/reports/jacoco/test/jacocoTestReport.xml
framework/build/reports/jacoco/test/jacocoTestReport.xml
plugins/build/reports/jacoco/test/jacocoTestReport.xml
if-no-files-found: error

upload-base-coverage:
name: Upload Base Coverage to Codecov
needs: build-base-coverage
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- name: Checkout repo
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Download coverage artifacts
uses: actions/download-artifact@v7
with:
name: base-jacoco-xml
path: coverage-artifacts

- name: Show coverage files
run: find coverage-artifacts -type f | sort

- name: Upload base coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
directory: ./coverage-artifacts
root_dir: ./
gcov_executable: ''
override_branch: ${{ github.ref_name }}
fail_ci_if_error: true
verbose: true
73 changes: 73 additions & 0 deletions .github/workflows/coverage-upload.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Codecov Upload & Compare

on:
workflow_run:
workflows:
- Coverage Build
types:
- completed

permissions:
contents: read
actions: read
pull-requests: read

jobs:
upload-coverage:
name: Upload Coverage
if: >
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
outputs:
pr_number: ${{ steps.pr.outputs.pr_number }}

steps:
- name: Checkout repo
uses: actions/checkout@v5 # must download source code
with:
fetch-depth: 0
persist-credentials: false

- name: Download coverage artifact
uses: actions/download-artifact@v7
with:
name: jacoco-coverage
path: coverage
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Get PR details
id: pr
uses: actions/github-script@v8
with:
script: |
const headSha = context.payload.workflow_run.head_sha;
const headOwner = context.payload.workflow_run.head_repository.owner.login;
const headBranch = context.payload.workflow_run.head_branch;
const { data: pulls } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'all',
head: `${headOwner}:${headBranch}`,
});
const pr = pulls.find((p) => p.head.sha === headSha);
if (pr) {
core.setOutput('pr_number', pr.number);
core.setOutput('pr_sha', headSha);
core.setOutput('pr_branch', headBranch);
core.setOutput('base_sha', pr.base.sha);
} else {
core.setFailed(`No pull request found for commit ${headSha}`);
}

- name: Upload to Codecov
if: ${{ steps.pr.outputs.pr_number != '' }}
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
override_commit: ${{ steps.pr.outputs.pr_sha }}
override_branch: ${{ steps.pr.outputs.pr_branch }}
override_pr: ${{ steps.pr.outputs.pr_number }}
fail_ci_if_error: true
verbose: true
119 changes: 119 additions & 0 deletions .github/workflows/coverage-waiting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
name: Waiting Coverage project

on:
pull_request:
branches: [ 'develop', 'release_**' ]
types: [ opened, synchronize, reopened ]

permissions:
contents: read
checks: read
statuses: read
pull-requests: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
waiting-coverage-project:
name: waiting-coverage-report
runs-on: ubuntu-latest
timeout-minutes: 70

steps:
- name: Wait for codecov/project status
uses: actions/github-script@v8
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const ref = context.payload.pull_request.head.sha;

const targetContext = 'codecov/project';
const maxAttempts = 120; // 120 * 30s = 60 minutes
const intervalMs = 30 * 1000;

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

for (let attempt = 1; attempt <= maxAttempts; attempt++) {
core.info(`Polling attempt ${attempt}/${maxAttempts} for ${targetContext} on ${ref}`);

try {
// Check legacy commit statuses
const combined = await github.rest.repos.getCombinedStatusForRef({
owner,
repo,
ref,
per_page: 100
});

const statuses = combined.data.statuses || [];
const matchedStatus = statuses.find(s => s.context === targetContext);

if (matchedStatus) {
core.info(`Found commit status: ${matchedStatus.context} = ${matchedStatus.state}`);

if (matchedStatus.state === 'success') {
core.info(`${targetContext} succeeded.`);
return;
}

if (matchedStatus.state === 'failure' || matchedStatus.state === 'error') {
core.setFailed(`${targetContext} is ${matchedStatus.state}.`);
return;
}

// pending
await sleep(intervalMs);
continue;
}

// Check check-runs as a fallback
const checks = await github.rest.checks.listForRef({
owner,
repo,
ref,
per_page: 100
});

const checkRuns = checks.data.check_runs || [];
const matchedCheck = checkRuns.find(c => c.name === targetContext);

if (matchedCheck) {
core.info(
`Found check run: ${matchedCheck.name}, status=${matchedCheck.status}, conclusion=${matchedCheck.conclusion}`
);

if (matchedCheck.status === 'completed') {
if (matchedCheck.conclusion === 'success') {
core.info(`${targetContext} succeeded.`);
return;
}

core.setFailed(
`${targetContext} completed with conclusion=${matchedCheck.conclusion}.`
);
return;
}

// queued / in_progress
await sleep(intervalMs);
continue;
}

core.info(`${targetContext} not reported yet. Waiting...`);
} catch (error) {
core.warning(
`Attempt ${attempt}/${maxAttempts} failed with transient error: ${error.message}. Retrying in ${intervalMs / 1000}s...`
);
}

await sleep(intervalMs);
}

core.setFailed(
`Timed out waiting for ${targetContext} to report success on commit ${ref}.`
);
Loading
Loading