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) {
|
function isNativeBuildPath(filePath) {
|
||||||
const p = normalizePath(filePath);
|
const p = normalizePath(filePath);
|
||||||
if (!p) return false;
|
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 (
|
return (
|
||||||
p.startsWith('android/') ||
|
p.startsWith('android/') ||
|
||||||
p.startsWith('.github/') ||
|
p === '.github/workflows/android-build.yml' ||
|
||||||
|
p.startsWith('.github/scripts/') ||
|
||||||
p === 'pubspec.yaml' ||
|
p === 'pubspec.yaml' ||
|
||||||
p === 'pubspec.lock' ||
|
p === 'pubspec.lock' ||
|
||||||
p === 'analysis_options.yaml' ||
|
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:
|
outputs:
|
||||||
android_changed: ${{ steps.detector.outputs.android_changed }}
|
android_changed: ${{ steps.detector.outputs.android_changed }}
|
||||||
app_changed: ${{ steps.detector.outputs.app_changed }}
|
app_changed: ${{ steps.detector.outputs.app_changed }}
|
||||||
|
native_build_changed: ${{ steps.detector.outputs.native_build_changed }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue