-
Notifications
You must be signed in to change notification settings - Fork 9
177 lines (143 loc) · 7.18 KB
/
ci.yml
File metadata and controls
177 lines (143 loc) · 7.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
name: Lint and Test
on:
pull_request:
types:
- opened
- reopened
- synchronize
- ready_for_review
permissions:
contents: write
actions: read
pull-requests: write
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['8.1', '8.2', '8.3', '8.4']
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
- name: Cache Composer dependencies
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Check Commits
id: commit_check # Add an ID to access outputs
run: |
# Don't warn about detached head.
git config advice.detachedHead false
git fetch --all --prune # Fetch all refs and remove stale remote-tracking branches
# Ensure the local 'default' branch reflects 'origin/default'
git checkout -B default origin/default
# Checkout the actual head of the pull request branch
git checkout ${{ github.event.pull_request.head.sha }}
echo "Running check-commits.sh to analyze PR commits..."
script_exit_code=0
# Execute the script, capturing all its stderr.
script_stderr_output=$(bash ${{ github.workspace }}/devops/scripts/check-commits.sh 2>&1) || script_exit_code=$?
echo "--- Script Standard Error Output (and stdout if any) ---"
echo "${script_stderr_output}"
echo "--- End Script Output ---"
echo "Script exit code: $script_exit_code"
# Script itself failed (e.g., mixed files in a single commit, forbidden files)
commit_script_failed_output="false"
if [ "$script_exit_code" -ne 0 ]; then
commit_script_failed_output="true"
fi
echo "commit_script_failed=${commit_script_failed_output}" >> $GITHUB_OUTPUT
# Mixture of 'normal' and 'non-release' commit types across the PR
has_normal_commits=$(echo "${script_stderr_output}" | grep -c "is a normal commit" || true)
has_nonrelease_commits=$(echo "${script_stderr_output}" | grep -c "is a non-release commit" || true)
echo "Normal commits found: $has_normal_commits"
echo "Non-release commits found: $has_nonrelease_commits"
mixed_commit_types_in_pr_output="false"
if [ "$has_normal_commits" -gt 0 ] && [ "$has_nonrelease_commits" -gt 0 ]; then
mixed_commit_types_in_pr_output="true"
fi
echo "mixed_commit_types_in_pr=${mixed_commit_types_in_pr_output}" >> $GITHUB_OUTPUT
# Prepare overall error summary for the comment
final_error_summary=""
if [ "${commit_script_failed_output}" == "true" ]; then
# Extract lines that look like errors from the script
script_reported_errors=$(echo "${script_stderr_output}" | grep -E "contains both release and nonrelease changes|contains forbidden files" || true)
if [ -n "${script_reported_errors}" ]; then
final_error_summary+="Script reported the following issues with specific commits:\n${script_reported_errors}\n\n"
else
# If script failed but no specific errors were grepped, include the full output for context
final_error_summary+="The check-commits.sh script failed (exit code $script_exit_code). Full script output for context:\n${script_stderr_output}\n\n"
fi
fi
if [ "${mixed_commit_types_in_pr_output}" == "true" ]; then
final_error_summary+="This PR contains a mixture of 'normal' (release) commits and 'non-release' (internal) commits. This requires careful merging (e.g., rebase and merge) to ensure only 'normal' commits are deployed to public upstream if that's the intent."
fi
echo "final_error_summary<<ERROR_SUMMARY_EOF" >> $GITHUB_OUTPUT
echo -e "${final_error_summary}" >> $GITHUB_OUTPUT
echo "ERROR_SUMMARY_EOF" >> $GITHUB_OUTPUT
- name: Comment on PR if commit check failed or types are mixed
# Trigger if the script failed OR if there's a mix of commit types
if: steps.commit_check.outputs.commit_script_failed == 'true' || steps.commit_check.outputs.mixed_commit_types_in_pr == 'true'
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
ERROR_DETAILS: ${{ steps.commit_check.outputs.final_error_summary }}
run: |
COMMENT_MARKER="<!-- GITHUB_ACTIONS_COMMIT_CHECK_COMMENT -->"
# Check for existing comment with the marker
EXISTING_COMMENT_ID=$(gh pr view $PR_NUMBER --json comments -q ".comments[] | select(.body | contains(\"${COMMENT_MARKER}\")) | .id" || echo "")
if [ -n "$EXISTING_COMMENT_ID" ]; then
echo "Commit check comment already exists (ID: $EXISTING_COMMENT_ID). Skipping new comment."
else
echo "No existing commit check comment found. Posting a new one."
COMMENT_BODY="Hi from your friendly robot! :robot: ${COMMENT_MARKER}
Please review the commit checks for this PR:
> ${ERROR_DETAILS}
If issues are present, please ensure commits modify either 'normal' or 'non-release' files (not a mix within a single commit) and do not contain forbidden files.
If this PR intentionally mixes 'normal' and 'non-release' commit types, remember to use **rebase and merge** rather than **squash** when merging to preserve individual commit integrity for the deploy process."
gh pr comment $PR_NUMBER -b "$COMMENT_BODY"
fi
- name: Check Composer lock file is up to date
run: composer validate --no-check-all
- name: Install Composer dependencies
run: composer update --no-progress --prefer-dist --optimize-autoloader
- name: Run lints
run: |
composer lint:devops
composer lint
- name: Run tests
run: composer test
- name: Install bats
uses: bats-core/bats-action@2.0.0
- name: Test Helper functions
env:
CI: 1
run: |
bats -p -t .github/tests/1-test-update-php.bats
- name: Create failure status artifact
if: failure()
run: |
# In the case of a failure, remove the previous status, whatever it was, and update it to 1.
if [ -f status-${{ matrix.php-version }}-${{ github.sha }}.txt ]; then
rm status-${{ matrix.php-version }}-${{ github.sha }}.txt
fi
echo "1" > status-${{ matrix.php-version }}-${{ github.sha }}.txt
- name: Create success status artifact
if: success()
run: |
# Only create a status file if it doesn't already exist.
if [ ! -f status-${{ matrix.php-version }}-${{ github.sha }}.txt ]; then
echo "0" > status-${{ matrix.php-version }}-${{ github.sha }}.txt
fi
- name: Upload status artifacts
uses: actions/upload-artifact@v4
with:
name: status-${{ matrix.php-version }}-${{ github.sha }}
path: status-${{ matrix.php-version }}-${{ github.sha }}.txt