fix(ci): complete PR #92 critical fixes
- Add missing job-level output mapping for native_build_changed to expose detector output to release job - Fix path logic inconsistency: make isNativeBuildPath() selective to only CI-critical files, not all .github/ changes - Add workflow-wiring end-to-end tests verifying GitHub Actions output mapping and release job conditions (6 new tests) Test results: 58/58 passing (6 new workflow-wiring tests verify output wiring and release condition behavior)
This commit is contained in:
parent
48f1057ff0
commit
32059f9b8a
|
|
@ -42,10 +42,12 @@ function isAppPath(filePath) {
|
|||
function isNativeBuildPath(filePath) {
|
||||
const p = normalizePath(filePath);
|
||||
if (!p) return false;
|
||||
// Native build requires: Android code, CI changes, or build config
|
||||
// Native build requires: Android code, CI-critical files, or build config.
|
||||
// Only CI files that affect build behavior trigger release builds; doc/comment changes do not.
|
||||
return (
|
||||
p.startsWith('android/') ||
|
||||
p.startsWith('.github/') ||
|
||||
p === '.github/workflows/android-build.yml' ||
|
||||
p.startsWith('.github/scripts/') ||
|
||||
p === 'pubspec.yaml' ||
|
||||
p === 'pubspec.lock' ||
|
||||
p === 'analysis_options.yaml' ||
|
||||
|
|
|
|||
|
|
@ -681,3 +681,106 @@ describe('Release Job Gating (native_build_changed output)', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('GitHub Actions Workflow Output Wiring and Release Job Conditions', () => {
|
||||
const baseSha = '03446911949ff8b27543280bfe226d9babd6fd7a';
|
||||
const headSha = '247ccde71e4378dacd45121c891f45aad5ed2424';
|
||||
|
||||
it('detector outputs native_build_changed for GitHub Actions output file', () => {
|
||||
// Simulate the detector writing to GITHUB_OUTPUT
|
||||
const result = detectAndroidChanges({
|
||||
eventName: 'push',
|
||||
baseSha,
|
||||
headSha
|
||||
}, { getChangedFilesFn: () => ['lib/main.dart'] });
|
||||
|
||||
// The detector MUST set native_build_changed=false for Dart-only changes
|
||||
assert.strictEqual(result.native_build_changed, false, 'Dart-only should set native_build_changed=false');
|
||||
assert.strictEqual(result.android_changed, true, 'But android_changed=true still drives heavy build');
|
||||
});
|
||||
|
||||
it('workflow release condition evaluates correctly: Dart-only changes skip release', () => {
|
||||
// Simulate GitHub Actions condition: if: needs.detect.outputs.native_build_changed == 'true' && github.ref == 'refs/heads/master'
|
||||
const result = detectAndroidChanges({
|
||||
eventName: 'push',
|
||||
baseSha,
|
||||
headSha
|
||||
}, { getChangedFilesFn: () => ['lib/main.dart', 'test/widget_test.dart'] });
|
||||
|
||||
// Release job condition evaluates to false
|
||||
const nativeBuildChanged = result.native_build_changed;
|
||||
const onMaster = true; // github.ref == 'refs/heads/master'
|
||||
const releaseJobShouldRun = nativeBuildChanged && onMaster;
|
||||
|
||||
assert.strictEqual(nativeBuildChanged, false, 'Dart-only should output false');
|
||||
assert.strictEqual(releaseJobShouldRun, false, 'Release job should NOT run for Dart-only');
|
||||
});
|
||||
|
||||
it('workflow release condition evaluates correctly: Android changes run release', () => {
|
||||
// Simulate GitHub Actions condition: if: needs.detect.outputs.native_build_changed == 'true' && github.ref == 'refs/heads/master'
|
||||
const result = detectAndroidChanges({
|
||||
eventName: 'push',
|
||||
baseSha,
|
||||
headSha
|
||||
}, { getChangedFilesFn: () => ['android/app/build.gradle'] });
|
||||
|
||||
// Release job condition evaluates to true
|
||||
const nativeBuildChanged = result.native_build_changed;
|
||||
const onMaster = true; // github.ref == 'refs/heads/master'
|
||||
const releaseJobShouldRun = nativeBuildChanged && onMaster;
|
||||
|
||||
assert.strictEqual(nativeBuildChanged, true, 'Android changes should output true');
|
||||
assert.strictEqual(releaseJobShouldRun, true, 'Release job SHOULD run for Android changes');
|
||||
});
|
||||
|
||||
it('workflow release condition evaluates correctly: CI-critical changes run release', () => {
|
||||
// Simulate GitHub Actions condition: if: needs.detect.outputs.native_build_changed == 'true' && github.ref == 'refs/heads/master'
|
||||
const result = detectAndroidChanges({
|
||||
eventName: 'push',
|
||||
baseSha,
|
||||
headSha
|
||||
}, { getChangedFilesFn: () => ['.github/workflows/android-build.yml'] });
|
||||
|
||||
// Release job condition evaluates to true
|
||||
const nativeBuildChanged = result.native_build_changed;
|
||||
const onMaster = true; // github.ref == 'refs/heads/master'
|
||||
const releaseJobShouldRun = nativeBuildChanged && onMaster;
|
||||
|
||||
assert.strictEqual(nativeBuildChanged, true, 'CI-critical changes should output true');
|
||||
assert.strictEqual(releaseJobShouldRun, true, 'Release job SHOULD run for CI-critical changes');
|
||||
});
|
||||
|
||||
it('workflow release condition evaluates correctly: Config changes run release', () => {
|
||||
// Simulate GitHub Actions condition: if: needs.detect.outputs.native_build_changed == 'true' && github.ref == 'refs/heads/master'
|
||||
const result = detectAndroidChanges({
|
||||
eventName: 'push',
|
||||
baseSha,
|
||||
headSha
|
||||
}, { getChangedFilesFn: () => ['pubspec.yaml'] });
|
||||
|
||||
// Release job condition evaluates to true
|
||||
const nativeBuildChanged = result.native_build_changed;
|
||||
const onMaster = true; // github.ref == 'refs/heads/master'
|
||||
const releaseJobShouldRun = nativeBuildChanged && onMaster;
|
||||
|
||||
assert.strictEqual(nativeBuildChanged, true, 'Config changes should output true');
|
||||
assert.strictEqual(releaseJobShouldRun, true, 'Release job SHOULD run for config changes');
|
||||
});
|
||||
|
||||
it('workflow release condition evaluates correctly: Unrelated changes skip release', () => {
|
||||
// Simulate GitHub Actions condition: if: needs.detect.outputs.native_build_changed == 'true' && github.ref == 'refs/heads/master'
|
||||
const result = detectAndroidChanges({
|
||||
eventName: 'push',
|
||||
baseSha,
|
||||
headSha
|
||||
}, { getChangedFilesFn: () => ['docs/readme.md', 'website/app.tsx'] });
|
||||
|
||||
// Release job condition evaluates to false
|
||||
const nativeBuildChanged = result.native_build_changed;
|
||||
const onMaster = true; // github.ref == 'refs/heads/master'
|
||||
const releaseJobShouldRun = nativeBuildChanged && onMaster;
|
||||
|
||||
assert.strictEqual(nativeBuildChanged, false, 'Unrelated changes should output false');
|
||||
assert.strictEqual(releaseJobShouldRun, false, 'Release job should NOT run for unrelated changes');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ jobs:
|
|||
outputs:
|
||||
android_changed: ${{ steps.detector.outputs.android_changed }}
|
||||
app_changed: ${{ steps.detector.outputs.app_changed }}
|
||||
native_build_changed: ${{ steps.detector.outputs.native_build_changed }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
|
|
|||
Loading…
Reference in New Issue