fix(ci): separate PR validation from image publishing
Validate container builds inside CI for pull requests, and publish images only after CI succeeds on main or when a release tag is pushed.
This commit is contained in:
1 parent
1d009360be
commit
0e2bc31b73
3 files changed
+55
-14
No files matched your search
@@ -5,6 +5,8 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -49,3 +51,26 @@ jobs:
|
|||||||
NODE_ENV=dry-run node ./build/stand-alone/crawl.js
|
NODE_ENV=dry-run node ./build/stand-alone/crawl.js
|
||||||
NODE_ENV=dry-run node ./build/stand-alone/search.js
|
NODE_ENV=dry-run node ./build/stand-alone/search.js
|
||||||
NODE_ENV=dry-run node ./build/stand-alone/serp.js
|
NODE_ENV=dry-run node ./build/stand-alone/serp.js
|
||||||
|
|
||||||
|
validate-container:
|
||||||
|
name: Validate container build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: verify
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Prepare licensed assets
|
||||||
|
run: node ./scripts/prepare-licensed-assets.cjs
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Build container image without publishing
|
||||||
|
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: false
|
||||||
+14
-14
@@ -1,21 +1,12 @@
|
|||||||
name: Container Image
|
name: Container Image
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
workflow_run:
|
||||||
paths:
|
workflows:
|
||||||
- Dockerfile
|
- CI
|
||||||
- package.json
|
types:
|
||||||
- package-lock.json
|
- completed
|
||||||
- tsconfig.json
|
|
||||||
- integrity-check.cjs
|
|
||||||
- src/**
|
|
||||||
- public/**
|
|
||||||
- licensed/**
|
|
||||||
- scripts/**
|
|
||||||
- .github/workflows/image.yml
|
|
||||||
push:
|
push:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
tags:
|
tags:
|
||||||
- v*
|
- v*
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -31,11 +22,20 @@ concurrency:
|
|||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
name: Build container image
|
name: Build container image
|
||||||
|
if: |
|
||||||
|
github.event_name == 'workflow_dispatch' ||
|
||||||
|
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) ||
|
||||||
|
(github.event_name == 'workflow_run' &&
|
||||||
|
github.event.workflow_run.conclusion == 'success' &&
|
||||||
|
github.event.workflow_run.event == 'push' &&
|
||||||
|
github.event.workflow_run.head_branch == 'main')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 45
|
timeout-minutes: 45
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository
|
- name: Check out repository
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event_name == 'workflow_run' && github.event.workflow_run.head_sha || github.ref }}
|
||||||
|
|
||||||
- name: Prepare licensed assets
|
- name: Prepare licensed assets
|
||||||
run: node ./scripts/prepare-licensed-assets.cjs
|
run: node ./scripts/prepare-licensed-assets.cjs
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ test('container image workflow publishes to GHCR instead of legacy GCP registrie
|
|||||||
assert.doesNotMatch(workflow, /gcloud|us-docker\.pkg\.dev/);
|
assert.doesNotMatch(workflow, /gcloud|us-docker\.pkg\.dev/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('container image publishing waits for CI instead of running on pull requests directly', () => {
|
||||||
|
const workflow = read('.github/workflows/image.yml');
|
||||||
|
|
||||||
|
assert.match(workflow, /workflow_run:/);
|
||||||
|
assert.match(workflow, /workflows:\s*\n\s*- CI/);
|
||||||
|
assert.doesNotMatch(workflow, /pull_request:/);
|
||||||
|
});
|
||||||
|
|
||||||
test('dependabot config covers npm, docker, and github-actions updates', () => {
|
test('dependabot config covers npm, docker, and github-actions updates', () => {
|
||||||
const dependabot = read('.github/dependabot.yml');
|
const dependabot = read('.github/dependabot.yml');
|
||||||
|
|
||||||
@@ -53,6 +61,14 @@ test('CI workflow runs lint before tests and build', () => {
|
|||||||
assert.match(workflow, /run: npm run build/);
|
assert.match(workflow, /run: npm run build/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('CI validates Docker builds for pull requests without publishing images', () => {
|
||||||
|
const workflow = read('.github/workflows/ci.yml');
|
||||||
|
|
||||||
|
assert.match(workflow, /name: Validate container build/);
|
||||||
|
assert.match(workflow, /if: github\.event_name == 'pull_request'/);
|
||||||
|
assert.match(workflow, /push: false/);
|
||||||
|
});
|
||||||
|
|
||||||
test('Dockerfile is self-contained and no longer relies on curl-impersonate', () => {
|
test('Dockerfile is self-contained and no longer relies on curl-impersonate', () => {
|
||||||
const dockerfile = read('Dockerfile');
|
const dockerfile = read('Dockerfile');
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user