mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
ci: reduce SDK Java runner queueing (#8441)
* ci: cancel stale SDK Java pull request runs * fix(ci): preserve SDK Java push scheduling * ci: route trusted SDK Java jobs to ECS * ci: simplify SDK Java runner routing * fix(ci): provision Maven on ECS Java jobs * fix(ci): clean SDK daemon ECS test state * fix(ci): satisfy SDK Java lint
This commit is contained in:
3 files changed
+125
-8
No files matched your search
@@ -41,10 +41,18 @@ on:
|
||||
permissions:
|
||||
contents: 'read'
|
||||
|
||||
env:
|
||||
MAVEN_VERSION: '3.9.11'
|
||||
MAVEN_SHA512: 'bcfe4fe305c962ace56ac7b5fc7a08b87d5abd8b7e89027ab251069faebee516b0ded8961445d6d91ec1985dfe30f8153268843c89aa392733d1a3ec956c9978'
|
||||
|
||||
concurrency:
|
||||
group: 'sdk-java-${{ github.event.pull_request.number || github.run_id }}'
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: '${{ matrix.os }} / Java ${{ matrix.java }}'
|
||||
runs-on: '${{ matrix.os }}'
|
||||
runs-on: '${{ (matrix.os == ''ubuntu-latest'' && github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'' && (github.event_name == ''push'' || github.event.pull_request.head.repo.full_name == github.repository)) && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || matrix.os }}'
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -61,8 +69,32 @@ jobs:
|
||||
- os: 'windows-latest'
|
||||
java: '21'
|
||||
steps:
|
||||
- name: 'Restore workspace ownership'
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: |-
|
||||
set -uo pipefail
|
||||
RUNNER_UID="$(id -u)"
|
||||
RUNNER_GID="$(id -g)"
|
||||
if [ "$RUNNER_UID" != "0" ]; then
|
||||
chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace ownership; checkout may fail on leftover root-owned files"
|
||||
fi
|
||||
chmod -R u+rwX "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chmod -R u+rwX "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace write permissions; checkout may fail on leftover read-only files"
|
||||
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
|
||||
with:
|
||||
ref: "${{ (runner.environment == 'self-hosted' && github.event_name == 'pull_request' && format('refs/pull/{0}/head', github.event.pull_request.number)) || github.ref }}"
|
||||
|
||||
- name: 'Verify checkout includes expected head commit'
|
||||
if: "${{ runner.environment == 'self-hosted' && github.event_name == 'pull_request' }}"
|
||||
env:
|
||||
EXPECTED_SHA: '${{ github.event.pull_request.head.sha }}'
|
||||
run: |-
|
||||
if ! git merge-base --is-ancestor "${EXPECTED_SHA}" HEAD; then
|
||||
echo "::error::Checked out ref does not contain expected head ${EXPECTED_SHA}."
|
||||
git log --oneline --decorate -5
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: 'Set up Java'
|
||||
uses: 'actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654' # v5.2.0
|
||||
@@ -72,6 +104,15 @@ jobs:
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'packages/sdk-java/qwencode/pom.xml'
|
||||
|
||||
- name: 'Set up Maven (self-hosted)'
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: |-
|
||||
archive="${RUNNER_TEMP}/apache-maven-${MAVEN_VERSION}-bin.tar.gz"
|
||||
curl -fsSL "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/${MAVEN_VERSION}/apache-maven-${MAVEN_VERSION}-bin.tar.gz" -o "${archive}"
|
||||
echo "${MAVEN_SHA512} ${archive}" | sha512sum --check --status
|
||||
tar -xzf "${archive}" -C "${RUNNER_TEMP}"
|
||||
echo "${RUNNER_TEMP}/apache-maven-${MAVEN_VERSION}/bin" >> "${GITHUB_PATH}"
|
||||
|
||||
- name: 'Run Java SDK tests'
|
||||
working-directory: 'packages/sdk-java/qwencode'
|
||||
run: 'mvn --batch-mode --no-transfer-progress clean test'
|
||||
@@ -88,18 +129,56 @@ jobs:
|
||||
|
||||
daemon-e2e:
|
||||
name: 'Real daemon E2E / Java 11'
|
||||
runs-on: 'ubuntu-latest'
|
||||
runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'' && (github.event_name == ''push'' || github.event.pull_request.head.repo.full_name == github.repository)) && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || ''ubuntu-latest'' }}'
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: 'Restore workspace ownership'
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: |-
|
||||
set -uo pipefail
|
||||
RUNNER_UID="$(id -u)"
|
||||
RUNNER_GID="$(id -g)"
|
||||
if [ "$RUNNER_UID" != "0" ]; then
|
||||
chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace ownership; checkout may fail on leftover root-owned files"
|
||||
fi
|
||||
chmod -R u+rwX "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chmod -R u+rwX "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace write permissions; checkout may fail on leftover read-only files"
|
||||
|
||||
- name: 'Checkout'
|
||||
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
|
||||
with:
|
||||
ref: "${{ (runner.environment == 'self-hosted' && github.event_name == 'pull_request' && format('refs/pull/{0}/head', github.event.pull_request.number)) || github.ref }}"
|
||||
|
||||
- name: 'Set up Node.js'
|
||||
- name: 'Verify checkout includes expected head commit'
|
||||
if: "${{ runner.environment == 'self-hosted' && github.event_name == 'pull_request' }}"
|
||||
env:
|
||||
EXPECTED_SHA: '${{ github.event.pull_request.head.sha }}'
|
||||
run: |-
|
||||
if ! git merge-base --is-ancestor "${EXPECTED_SHA}" HEAD; then
|
||||
echo "::error::Checked out ref does not contain expected head ${EXPECTED_SHA}."
|
||||
git log --oneline --decorate -5
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Self-hosted can't reach nodejs.org reliably; reuse the machine's Node.
|
||||
- name: 'Set up Node.js 22 (hosted)'
|
||||
if: "${{ runner.environment == 'github-hosted' }}"
|
||||
uses: 'actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e' # v6.4.0
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: 'npm'
|
||||
|
||||
- name: 'Use pre-installed Node.js (self-hosted)'
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: |-
|
||||
if ! command -v node >/dev/null 2>&1; then
|
||||
echo "::error::Node.js is not on PATH for this self-hosted runner. Provision Node 22.x or set MAINTAINER_ECS_RUNNER_DISABLED=true."
|
||||
exit 1
|
||||
fi
|
||||
echo "Using pre-installed Node $(node -v) / npm $(npm -v)"
|
||||
if [[ "$(node -p 'process.versions.node.split(".")[0]')" != "22" ]]; then
|
||||
echo "::warning::Expected Node 22.x but found $(node -v); daemon E2E will run against the runner's Node."
|
||||
fi
|
||||
|
||||
- name: 'Set up Java'
|
||||
uses: 'actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654' # v5.2.0
|
||||
with:
|
||||
@@ -108,6 +187,15 @@ jobs:
|
||||
cache: 'maven'
|
||||
cache-dependency-path: 'packages/sdk-java/qwencode/pom.xml'
|
||||
|
||||
- name: 'Set up Maven (self-hosted)'
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: |-
|
||||
archive="${RUNNER_TEMP}/apache-maven-${MAVEN_VERSION}-bin.tar.gz"
|
||||
curl -fsSL "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/${MAVEN_VERSION}/apache-maven-${MAVEN_VERSION}-bin.tar.gz" -o "${archive}"
|
||||
echo "${MAVEN_SHA512} ${archive}" | sha512sum --check --status
|
||||
tar -xzf "${archive}" -C "${RUNNER_TEMP}"
|
||||
echo "${RUNNER_TEMP}/apache-maven-${MAVEN_VERSION}/bin" >> "${GITHUB_PATH}"
|
||||
|
||||
- name: 'Install Node.js dependencies'
|
||||
run: 'npm ci --prefer-offline --no-audit --progress=false'
|
||||
|
||||
|
||||
@@ -131,7 +131,6 @@ const daemon = spawn(
|
||||
let stderr = '';
|
||||
let javaTest: ChildProcess | undefined;
|
||||
let receivedSignal: NodeJS.Signals | undefined;
|
||||
let succeeded = false;
|
||||
daemon.stderr?.on('data', (chunk) => {
|
||||
stderr += chunk.toString();
|
||||
});
|
||||
@@ -297,7 +296,6 @@ try {
|
||||
'Java E2E completed without exercising the daemon model path; the integration tests may have been skipped',
|
||||
);
|
||||
}
|
||||
succeeded = true;
|
||||
} catch (error) {
|
||||
runFailure = error;
|
||||
}
|
||||
@@ -322,10 +320,14 @@ try {
|
||||
}
|
||||
process.off('SIGINT', handleSigint);
|
||||
process.off('SIGTERM', handleSigterm);
|
||||
if (succeeded && cleanupFailures.length === 0) {
|
||||
rmSync(temporary, { recursive: true, force: true });
|
||||
} else {
|
||||
if (process.env.QWEN_DAEMON_E2E_KEEP_STATE === '1') {
|
||||
console.error(`Retained Java daemon E2E state at ${temporary}`);
|
||||
} else {
|
||||
try {
|
||||
rmSync(temporary, { recursive: true, force: true });
|
||||
} catch (error) {
|
||||
cleanupFailures.push(error);
|
||||
}
|
||||
}
|
||||
if (receivedSignal !== undefined) {
|
||||
process.kill(process.pid, receivedSignal);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
const workflow = readFileSync('.github/workflows/sdk-java.yml', 'utf8');
|
||||
const job = (name) => {
|
||||
const start = workflow.indexOf(` ${name}:`);
|
||||
const next = workflow.slice(start + 1).search(/\n {2}[a-z0-9-]+:\n/);
|
||||
return workflow.slice(start, next < 0 ? undefined : start + 1 + next);
|
||||
};
|
||||
|
||||
describe('SDK Java self-hosted workflow guards', () => {
|
||||
it.each(['test', 'daemon-e2e'])('protects the %s job', (name) => {
|
||||
const block = job(name);
|
||||
for (const fragment of [
|
||||
"github.repository == ''QwenLM/qwen-code''",
|
||||
'github.event.pull_request.head.repo.full_name == github.repository',
|
||||
"vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true''",
|
||||
'fromJSON(\'\'["self-hosted", "linux", "x64", "ecs-qwen"]\'\')',
|
||||
"format('refs/pull/{0}/head', github.event.pull_request.number)",
|
||||
"EXPECTED_SHA: '${{ github.event.pull_request.head.sha }}'",
|
||||
'git merge-base --is-ancestor "${EXPECTED_SHA}" HEAD',
|
||||
'exit 1',
|
||||
]) {
|
||||
expect(block).toContain(fragment);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user