Skip to content

Commit 877025f

Browse files
authored
feat: Optimize CI/CD workflows with conditional job execution and file change detection (#10)
## Summary This PR significantly improves CI/CD efficiency by implementing conditional job execution based on file changes. Jobs now only run when relevant files are modified, reducing unnecessary workflow runs and improving build times. ## Key Improvements ### 🚀 Performance Optimization - **Smart File Change Detection**: Added `Detect Changes` job using `dorny/paths-filter` to identify modified file types - **Conditional Job Execution**: Jobs only run when their relevant files change (e.g., Go tests run only when `.go` files change) - **Resource Efficiency**: Reduces CI minutes usage by skipping irrelevant jobs ### 📋 Workflow Changes #### CI Workflow (`ci.yml`) - Added `changes` job that detects modifications in: - Go files (`*.go`, `go.mod`, `go.sum`, `.golangci.yml`) - Scripts and workflow files - Made all jobs conditional based on detected changes: - `lint`: Runs only when Go files change - `test`: Runs only when Go files change - `acceptance-test`: Runs only when Go files change - `build-provider`: Runs only when Go files change - `terraform-compatibility`: Runs only when Go files change - Updated `ci-status` job to handle skipped jobs correctly #### Validation Workflow (`validation.yml`) - Added file change detection for: - Markdown files (`*.md`) - YAML files (`*.yml`, `*.yaml`) - JSON files (`*.json`, `*.jsonc`) - Terraform files (`*.tf`, `*.tfvars`) - Scripts - Made validation jobs conditional: - `file-validation`: Runs specific checks only when relevant files change - `markdown-lint`: Runs only when Markdown files change - `terraform-fmt`: Runs only when Terraform files change #### Pre-release Workflow - **Separated Concerns**: Extracted pre-release job into dedicated workflow (`.github/workflows/pre-release.yml`) - **Simplified Triggers**: Removed `push` triggers from `ci.yml` and `pre-commit.yml` - **Better Organization**: Pre-release now triggers only on pushes to `main` branch ### 🔧 Technical Details #### Status Check Script Enhancement Updated `scripts/ci-status-check.sh` to properly handle job statuses: - `skipped` jobs are now considered acceptable (when no relevant files changed) - Better status reporting with counts of successful vs skipped jobs - Improved error handling for cancelled jobs ## Benefits 1. **Faster PR Feedback**: Developers get quicker CI results by running only relevant checks 2. **Cost Savings**: Reduced GitHub Actions minutes usage 3. **Better Maintainability**: Clearer separation of concerns with dedicated workflows 4. **Improved Developer Experience**: Less waiting for irrelevant jobs to complete ## Testing - All conditional logic has been tested with various file change scenarios - Status checks properly handle skipped jobs - Pre-release workflow functions independently on main branch ## Migration Notes No action required. These changes are backward compatible and will automatically optimize future CI runs.
1 parent 1fe1955 commit 877025f

5 files changed

Lines changed: 263 additions & 145 deletions

File tree

.github/workflows/ci.yml

Lines changed: 48 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
name: CI
22

33
on:
4-
push:
5-
branches:
6-
- main
7-
- develop
84
pull_request:
95
branches:
106
- main
@@ -21,9 +17,35 @@ permissions:
2117
pull-requests: write
2218

2319
jobs:
20+
changes:
21+
name: Detect Changes
22+
runs-on: ubuntu-latest
23+
outputs:
24+
go: ${{ steps.filter.outputs.go }}
25+
scripts: ${{ steps.filter.outputs.scripts }}
26+
steps:
27+
- name: Checkout code
28+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
29+
30+
- name: Check for file changes
31+
uses: dorny/paths-filter@v3
32+
id: filter
33+
with:
34+
filters: |
35+
go:
36+
- '**/*.go'
37+
- 'go.mod'
38+
- 'go.sum'
39+
- '.golangci.yml'
40+
scripts:
41+
- 'scripts/**'
42+
- '.github/workflows/ci.yml'
43+
2444
lint:
2545
name: Lint
2646
runs-on: ubuntu-latest
47+
needs: changes
48+
if: needs.changes.outputs.go == 'true'
2749
steps:
2850
- name: Checkout code
2951
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
@@ -37,12 +59,25 @@ jobs:
3759
- name: Run go mod tidy
3860
run: go mod tidy
3961

62+
- name: Check for Go file changes
63+
uses: dorny/paths-filter@v3
64+
id: filter
65+
with:
66+
filters: |
67+
go:
68+
- '**/*.go'
69+
- 'go.mod'
70+
- 'go.sum'
71+
- '.golangci.yml'
72+
4073
- name: Run golangci-lint
74+
if: steps.filter.outputs.go == 'true'
4175
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8
4276
with:
4377
version: ${{ env.GOLANGCI_LINT_VERSION }}
4478

4579
- name: Check code formatting
80+
if: steps.filter.outputs.go == 'true'
4681
run: |
4782
if [ -n "$(gofmt -l .)" ]; then
4883
echo "The following files need formatting:"
@@ -53,6 +88,8 @@ jobs:
5388
test:
5489
name: Test
5590
runs-on: ubuntu-latest
91+
needs: changes
92+
if: needs.changes.outputs.go == 'true'
5693
steps:
5794
- name: Checkout code
5895
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
@@ -95,7 +132,8 @@ jobs:
95132
acceptance-test:
96133
name: Acceptance Test
97134
runs-on: ubuntu-latest
98-
needs: test
135+
needs: [changes, test]
136+
if: needs.changes.outputs.go == 'true'
99137
steps:
100138
- name: Checkout code
101139
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
@@ -149,7 +187,8 @@ jobs:
149187
build-provider:
150188
name: Build Provider
151189
runs-on: ubuntu-latest
152-
needs: test
190+
needs: [changes, test]
191+
if: needs.changes.outputs.go == 'true'
153192
steps:
154193
- name: Checkout code
155194
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
@@ -184,7 +223,8 @@ jobs:
184223
terraform-compatibility:
185224
name: Terraform Compatibility Test
186225
runs-on: ubuntu-latest
187-
needs: build-provider
226+
needs: [changes, build-provider]
227+
if: needs.changes.outputs.go == 'true'
188228
strategy:
189229
fail-fast: false
190230
matrix:
@@ -260,140 +300,13 @@ jobs:
260300
# Clean up test data
261301
rm -rf test-data
262302
263-
pre-release:
264-
name: Pre-release
265-
runs-on: ubuntu-latest
266-
needs: [lint, test, acceptance-test, terraform-compatibility]
267-
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request' && github.actor != 'dependabot[bot]'
268-
permissions:
269-
contents: write
270-
id-token: write
271-
attestations: write
272-
steps:
273-
- name: Checkout code
274-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
275-
with:
276-
fetch-depth: 0
277-
278-
- name: Check for Go file changes
279-
id: go_changes
280-
run: |
281-
# Get the latest tag
282-
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
283-
284-
if [ -z "$LATEST_TAG" ]; then
285-
echo "No previous tags found, assuming Go files changed"
286-
echo "changed=true" >> $GITHUB_OUTPUT
287-
else
288-
# Check if any Go files changed since the last tag
289-
GO_CHANGES=$(git diff --name-only ${LATEST_TAG}..HEAD -- '*.go' 'go.mod' 'go.sum' | wc -l)
290-
291-
if [ "$GO_CHANGES" -gt 0 ]; then
292-
echo "Go files changed since ${LATEST_TAG}"
293-
echo "changed=true" >> $GITHUB_OUTPUT
294-
git diff --name-only ${LATEST_TAG}..HEAD -- '*.go' 'go.mod' 'go.sum'
295-
else
296-
echo "No Go files changed since ${LATEST_TAG}"
297-
echo "changed=false" >> $GITHUB_OUTPUT
298-
fi
299-
fi
300-
301-
- name: Set up Go
302-
if: steps.go_changes.outputs.changed == 'true'
303-
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5
304-
with:
305-
go-version: ${{ env.GO_VERSION }}
306-
cache: true
307-
308-
- name: Import GPG key
309-
if: steps.go_changes.outputs.changed == 'true'
310-
id: import_gpg
311-
uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6
312-
with:
313-
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
314-
passphrase: ${{ secrets.GPG_PASSPHRASE }}
315-
316-
- name: Generate snapshot version
317-
if: steps.go_changes.outputs.changed == 'true'
318-
id: version
319-
run: |
320-
# Get the latest release tag (exclude pre-release tags)
321-
LATEST_TAG=$(git tag -l 'v*' | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n1 || echo "v0.0.0")
322-
if [ -z "$LATEST_TAG" ]; then
323-
LATEST_TAG="v0.0.0"
324-
fi
325-
echo "Latest release tag: ${LATEST_TAG}"
326-
327-
# Remove 'v' prefix
328-
VERSION=${LATEST_TAG#v}
329-
echo "Version without prefix: ${VERSION}"
330-
331-
# Parse version components
332-
IFS='.' read -r major minor patch <<< "$VERSION"
333-
echo "Version components: major=${major}, minor=${minor}, patch=${patch}"
334-
335-
# Generate new version
336-
NEW_VERSION="${major}.${minor}.$((patch + 1))-dev.$(date +%Y%m%d%H%M%S)+$(git rev-parse --short HEAD)"
337-
echo "Pre-release version: ${NEW_VERSION}"
338-
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
339-
340-
- name: Run GoReleaser (snapshot)
341-
if: steps.go_changes.outputs.changed == 'true'
342-
uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6
343-
with:
344-
version: latest
345-
args: release --snapshot --skip=sign --clean --skip=validate
346-
env:
347-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
348-
349-
- name: Generate pre-release attestations
350-
if: steps.go_changes.outputs.changed == 'true'
351-
uses: actions/attest-build-provenance@96b4a1ef7235a096b17240c259729fdd70c83d45 # v2
352-
with:
353-
subject-path: |
354-
dist/*.zip
355-
dist/*_checksums.txt
356-
357-
- name: Upload artifacts
358-
if: steps.go_changes.outputs.changed == 'true'
359-
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
360-
with:
361-
name: pre-release-artifacts
362-
path: dist/*
363-
364-
- name: Create GitHub pre-release
365-
if: steps.go_changes.outputs.changed == 'true'
366-
uses: softprops/action-gh-release@72f2c25fcb47643c292f7107632f7a47c1df5cd8 # v2
367-
with:
368-
name: "Development Build v${{ steps.version.outputs.version }}"
369-
tag_name: "v${{ steps.version.outputs.version }}"
370-
prerelease: true
371-
draft: false
372-
files: |
373-
dist/*.zip
374-
dist/*_checksums.txt
375-
body: |
376-
## Development Build
377-
378-
This is an automated development build from commit ${{ github.sha }}.
379-
380-
**⚠️ This is a pre-release version and should not be used in production.**
381-
382-
### Commit Information
383-
- SHA: ${{ github.sha }}
384-
- Author: ${{ github.actor }}
385-
- Message: ${{ github.event.head_commit.message }}
386-
387-
### Installation
388-
389-
Download the appropriate archive for your platform and extract the provider binary.
390303
391304
392305
# Job to consolidate status for PR checks
393306
ci-status:
394307
name: CI Status
395308
runs-on: ubuntu-latest
396-
needs: [lint, test, acceptance-test, terraform-compatibility]
309+
needs: [changes, lint, test, acceptance-test, terraform-compatibility]
397310
if: always()
398311
steps:
399312
- name: Checkout code

.github/workflows/pre-commit.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ on:
77
- edited
88
- synchronize
99
branches: [ main ]
10-
push:
11-
branches: [ main ]
1210

1311
permissions:
1412
contents: read

0 commit comments

Comments
 (0)