Skip to content

ci: add multi-platform build tests and system-test workflows #70

ci: add multi-platform build tests and system-test workflows

ci: add multi-platform build tests and system-test workflows #70

Workflow file for this run

name: PR Check
on:
push:
branches: [ 'master', 'release_**' ]
pull_request:
branches: [ 'develop', 'release_**' ]
types: [ opened, edited, synchronize, reopened ]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
pr-lint:
name: PR Lint
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Validate PR title and description
uses: actions/github-script@v7
with:
script: |
const title = context.payload.pull_request.title;
const body = context.payload.pull_request.body;
const errors = [];
const warnings = [];
const allowedTypes = ['feat','fix','refactor','docs','style','test','chore','ci','perf','build','revert'];
const knownScopes = [
'framework','chainbase','actuator','consensus','common','crypto','plugins','protocol',
'net','db','vm','tvm','api','jsonrpc','rpc','http','event','config',
'block','proposal','trie','log','metrics','test','docker','version',
'freezeV2','DynamicEnergy','stable-coin','reward','lite','toolkit'
];
// 1. Title length check
if (!title || title.trim().length < 10) {
errors.push('PR title is too short (minimum 10 characters).');
}
if (title && title.length > 72) {
errors.push(`PR title is too long (${title.length}/72 characters).`);
}
// 2. Conventional format check
const conventionalRegex = /^(feat|fix|refactor|docs|style|test|chore|ci|perf|build|revert)(\([^)]+\))?:\s\S.*/;
if (title && !conventionalRegex.test(title)) {
errors.push(
'PR title must follow conventional format: `type(scope): description`\n' +
' Allowed types: ' + allowedTypes.map(t => `\`${t}\``).join(', ') + '\n' +
' Example: `feat(tvm): add blob opcodes`'
);
}
// 3. No trailing period
if (title && title.endsWith('.')) {
errors.push('PR title should not end with a period (.).');
}
// 4. Description part should not start with a capital letter
if (title) {
const descMatch = title.match(/^\w+(?:\([^)]+\))?:\s*(.+)/);
if (descMatch) {
const desc = descMatch[1];
if (/^[A-Z]/.test(desc)) {
errors.push('Description should not start with a capital letter.');
}
}
}
// 5. Scope validation (warning only)
if (title) {
const scopeMatch = title.match(/^\w+\(([^)]+)\):/);
if (scopeMatch && !knownScopes.includes(scopeMatch[1])) {
warnings.push(`Unknown scope \`${scopeMatch[1]}\`. See CONTRIBUTING.md for known scopes.`);
}
}
// 6. PR description check
if (!body || body.trim().length < 20) {
errors.push('PR description is too short or empty (minimum 20 characters). Please describe what this PR does and why.');
}
// Output warnings
for (const w of warnings) {
core.warning(w);
}
// Output result
if (errors.length > 0) {
const docLink = 'See [CONTRIBUTING.md](https://github.com/' + context.repo.owner + '/' + context.repo.repo + '/blob/develop/CONTRIBUTING.md#pull-request-guidelines) for details.';
const message = '### PR Lint Failed\n\n' + errors.map(e => `- ${e}`).join('\n') + '\n\n' + docLink;
core.setFailed(message);
} else {
core.info('PR lint passed.');
}
checkstyle:
name: Checkstyle
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle-wrapper.properties') }}
restore-keys: ${{ runner.os }}-gradle-
- name: Run Checkstyle
run: ./gradlew :framework:checkstyleMain :framework:checkstyleTest :plugins:checkstyleMain
- name: Upload Checkstyle reports
if: failure()
uses: actions/upload-artifact@v4
with:
name: checkstyle-reports
path: |
framework/build/reports/checkstyle/
plugins/build/reports/checkstyle/
build:
name: Build ${{ matrix.os-name }}(JDK ${{ matrix.java }} / ${{ matrix.arch }})
if: github.event.action != 'edited' && !failure()
needs: [pr-lint, checkstyle]
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- java: '8'
runner: ubuntu-latest
os-name: ubuntu
arch: x86_64
- java: '17'
runner: ubuntu-24.04-arm
os-name: ubuntu
arch: aarch64
- java: '8'
runner: macos-26-intel
os-name: macos
arch: x86_64
- java: '17'
runner: macos-26
os-name: macos
arch: aarch64
steps:
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-${{ matrix.arch }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle-wrapper.properties') }}
restore-keys: ${{ runner.os }}-${{ matrix.arch }}-gradle-
- name: Build
run: ./gradlew clean build --no-daemon
docker-build-rockylinux:
name: Build rockylinux (JDK 8 / x86_64)
if: github.event.action != 'edited' && !failure()
needs: [pr-lint, checkstyle]
runs-on: ubuntu-latest
container:
image: rockylinux:8
env:
GRADLE_USER_HOME: /github/home/.gradle
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies (Rocky 8 + JDK8)
run: |
set -euxo pipefail
dnf -y install java-1.8.0-openjdk-devel git wget unzip which jq bc curl glibc-langpack-en
dnf -y groupinstall "Development Tools"
- name: Check Java version
run: java -version
- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
/github/home/.gradle/caches
/github/home/.gradle/wrapper
key: ${{ runner.os }}-rockylinux-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-rockylinux-gradle-
- 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
- name: Generate JaCoCo report
run: ./gradlew jacocoTestReport --no-daemon --no-build-cache
- name: Upload JaCoCo artifacts
uses: actions/upload-artifact@v4
with:
name: jacoco-rockylinux
path: |
**/build/reports/jacoco/test/jacocoTestReport.xml
**/build/reports/**
**/build/test-results/**
if-no-files-found: error
docker-build-debian11:
name: Build debian11 (JDK 8 / x86_64)
if: github.event.action != 'edited' && !failure()
needs: [pr-lint, checkstyle]
runs-on: ubuntu-latest
container:
image: eclipse-temurin:8-jdk # base image is Debian 11 (Bullseye)
defaults:
run:
shell: bash
env:
GRADLE_USER_HOME: /github/home/.gradle
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install dependencies (Debian + build tools)
run: |
set -euxo pipefail
apt-get update
apt-get install -y git wget unzip build-essential curl jq
- name: Check Java version
run: java -version
- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
/github/home/.gradle/caches
/github/home/.gradle/wrapper
key: ${{ runner.os }}-debian11-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-debian11-gradle-
- name: Grant execute permission
run: chmod +x gradlew
- name: Build
run: ./gradlew clean build --no-daemon --no-build-cache