Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/actionlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ paths:
ignore:
# [SC2129](https://www.shellcheck.net/wiki/SC2129) is ignored because it is a stylistic issue.
- 'shellcheck reported issue in this script: SC2129:.+'
# `queue` is a real concurrency key, but actionlint does not know it
# yet, and its last release predates the feature. Tracked upstream in
# https://github.com/rhysd/actionlint/issues/654.
- 'unexpected key "queue" for "concurrency" section.+'
.github/workflows/end2end-test.yml:
ignore:
# This file gets created in the step prior.
Expand Down
67 changes: 67 additions & 0 deletions .github/workflows/bundle-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ jobs:
runs-on: 'ubuntu-24.04'
permissions:
contents: read
# Only used on a fork, where the action falls back to commenting and
# its own failure handling takes over. See `use-check` below.
pull-requests: write
checks: write
timeout-minutes: 15

steps:
Expand All @@ -67,9 +70,73 @@ jobs:
uses: ./.github/setup-npm

- uses: preactjs/compressed-size-action@f322c295dde06a1cb7ccaef105732dd8a726d1d9 # v2.10.0
id: size
with:
omit-unchanged: true
repo-token: '${{ secrets.GITHUB_TOKEN }}'
pattern: '{build/scripts/**/*.min.js,build/styles/**/*.css,build/modules/**/*.min.js}'
clean-script: 'distclean'
build-script: 'build'
# Report a check rather than a comment, leaving the size report
# to the unified comment. Not on a fork: its token cannot create
# a check, and the check path, unlike the comment path, does not
# catch that failure.
use-check: ${{ github.event.pull_request.head.repo.full_name == github.repository }}

- name: Save the size report
if: ${{ !cancelled() && steps.size.outputs.comment-body }}
env:
# Through the environment, never interpolated into the script.
BODY: ${{ steps.size.outputs.comment-body }}
run: |
mkdir -p "${RUNNER_TEMP}/pr-meta"
# Drop the action's own footer, which the unified comment replaces.
printf '%s' "$BODY" | sed '/compressed-size-action<\/sub>/d' > "${RUNNER_TEMP}/pr-meta/body.md"

- name: Upload the size report
if: ${{ !cancelled() && steps.size.outputs.comment-body }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: pr-meta--bundle-size
path: ${{ runner.temp }}/pr-meta
if-no-files-found: ignore

pr-meta:
name: Update PR meta comment
needs: build
# Runs even when the build failed, so a stale size report is cleared.
# Skipped on a fork, whose token cannot write a comment.
if: ${{ !cancelled() && github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: 'ubuntu-24.04'
permissions:
contents: read
pull-requests: write
timeout-minutes: 5
# Every writer of this comment shares one lock, across workflows. The
# default `queue: single` would cancel a pending writer once a third
# arrived, silently dropping its section.
concurrency:
group: pr-meta-${{ github.event.number }}
cancel-in-progress: false
queue: max

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
sparse-checkout: tools/pr-meta
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
continue-on-error: true
with:
name: pr-meta--bundle-size
path: pr-meta

- uses: ./tools/pr-meta
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
section: bundle-size
body-path: pr-meta/body.md
commit-sha: ${{ github.event.pull_request.head.sha }}
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
55 changes: 51 additions & 4 deletions .github/workflows/end2end-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,6 @@ jobs:
runs-on: 'ubuntu-24.04'
permissions:
contents: read
# Needed to comment the flaky tests report on the pull request.
pull-requests: write
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -275,9 +273,58 @@ jobs:
name: flaky-tests-report
path: flaky-tests

- name: Report flaky tests
- name: Render the flaky tests report
if: ${{ steps.download-flaky-tests-report.outcome == 'success' }}
uses: ./packages/report-flaky-tests
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
artifact-path: flaky-tests
output-path: pr-meta/body.md

- name: Upload the flaky tests report
if: ${{ steps.download-flaky-tests-report.outcome == 'success' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: pr-meta--flaky-tests
path: pr-meta
if-no-files-found: ignore

pr-meta:
name: Update PR meta comment
needs: merge-artifacts
# Runs on every pull request, including the clean ones: a run with no
# flaky test uploads no report, and the empty section clears a stale one.
# Only when the job above succeeded, though, since a missing report then
# means the run was clean rather than that rendering it failed.
# Skipped on a fork, whose token cannot write a comment.
if: ${{ needs.merge-artifacts.result == 'success' && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: 'ubuntu-24.04'
permissions:
contents: read
pull-requests: write
timeout-minutes: 5
# Shared with every other writer of this comment. See bundle-size.yml.
concurrency:
group: pr-meta-${{ github.event.number }}
cancel-in-progress: false
queue: max

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
sparse-checkout: tools/pr-meta
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
continue-on-error: true
with:
name: pr-meta--flaky-tests
path: pr-meta

- uses: ./tools/pr-meta
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
section: flaky-tests
body-path: pr-meta/body.md
commit-sha: ${{ github.event.pull_request.head.sha }}
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
82 changes: 73 additions & 9 deletions .github/workflows/enforce-pr-labels.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,89 @@
name: Enforce labels on Pull Request
on:
pull_request_target:
types: [labeled, unlabeled, ready_for_review, review_requested]
types:
[
opened,
reopened,
labeled,
unlabeled,
ready_for_review,
review_requested,
]

# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}

jobs:
type-related-labels:
name: Check the type label
runs-on: 'ubuntu-24.04'
if: ${{ github.event.pull_request.state == 'open' }}
permissions:
contents: read
pull-requests: write
timeout-minutes: 5
# Shared with every other writer of this comment. See bundle-size.yml.
concurrency:
group: pr-meta-${{ github.event.number }}
cancel-in-progress: false
queue: max

steps:
- uses: mheap/github-action-required-labels@23e10fde7e062233401931a0eece796cd9bf3177 # v5.6.0
# A `pull_request_target` job has a writable token, so it checks out
# the base branch it was triggered on, never the pull request's head.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
mode: exactly
count: 1
labels: '^\[Type\]'
use_regex: true
add_comment: true
message: "**Warning: Type of PR label mismatch**\n\n To merge this PR, it requires {{ errorString }} {{ count }} label indicating the type of PR. Other labels are optional and not being checked here. \n- **Required label**: Any label starting with `[Type]`.\n- **Labels found**: {{ applied }}.\n\nRead more about [Type labels in Gutenberg](https://github.com/WordPress/gutenberg/labels?q=type). Don't worry if you don't have the required permissions to add labels; the PR reviewer should be able to help with the task."
exit_type: failure
sparse-checkout: tools/pr-meta
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Check for a type label
id: check
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.number }}
REPO: ${{ github.repository }}
run: |
mkdir -p pr-meta

# Read the labels now rather than from the event payload. Runs
# queue behind each other on the shared lock, so an older one
# can arrive after a newer one already fixed the labels.
type_labels="$(gh api "repos/${REPO}/issues/${PR_NUMBER}/labels" \
--jq '[ .[].name | select( startswith( "[Type]" ) ) ]')"
count="$(printf '%s' "$type_labels" | jq 'length')"

if [ "$count" -eq 1 ]; then
echo "ok=true" >> "$GITHUB_OUTPUT"
exit 0
fi

echo "ok=false" >> "$GITHUB_OUTPUT"
applied="$(printf '%s' "$type_labels" | jq -r 'if length == 0 then "none" else join( ", " ) end')"

cat > pr-meta/body.md <<EOF
This pull request needs exactly one label indicating its type, and has ${count}.

- Required: any label starting with \`[Type]\`.
- Found: ${applied}.

Read more about [Type labels in Gutenberg](https://github.com/WordPress/gutenberg/labels?q=type). If you cannot add labels yourself, a reviewer can do it for you.
EOF

# Runs whatever the check found, since an empty section is what
# clears the warning once the labels are right. Not when the check
# itself failed: no body file then means "labels are fine", and a
# failed API call would erase a warning nothing had disproved.
- name: Report the result
if: ${{ !cancelled() && steps.check.outcome == 'success' }}
uses: ./tools/pr-meta
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
section: labels
body-path: pr-meta/body.md

- name: Require exactly one type label
if: ${{ steps.check.outputs.ok != 'true' }}
run: exit 1
78 changes: 78 additions & 0 deletions .github/workflows/performance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@ jobs:
- name: Add workflow summary
run: cat "${WP_ARTIFACTS_PATH}/summary.md" >> "$GITHUB_STEP_SUMMARY"

- name: Archive performance summary
if: success()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: performance-summary-${{ matrix.shard }}
path: ${{ env.WP_ARTIFACTS_PATH }}/summary.md
if-no-files-found: ignore

- name: Archive performance results
if: success()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
Expand Down Expand Up @@ -257,6 +265,38 @@ jobs:
name: performance-results
path: ${{ env.WP_ARTIFACTS_PATH }}/*.performance-results*.json

- name: Download shard summaries
id: download-summaries
if: ${{ github.event_name == 'pull_request' }}
continue-on-error: true
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: performance-summary-*
path: ${{ env.WP_ARTIFACTS_PATH }}/summaries

- name: Merge shard summaries
if: ${{ steps.download-summaries.outcome == 'success' }}
run: |
mkdir -p pr-meta

# Every shard renders the same heading and preamble above its
# own suites, so keep them once and take only the tables from
# each. One directory per shard, ordered by name.
printf 'Client side metrics **exclude** the server response time.\n\n' > pr-meta/body.md
find "${WP_ARTIFACTS_PATH}/summaries" -name summary.md -print0 \
| sort -z \
| xargs -0 sed -e '/^## Performance Test Results$/d' \
-e '/^Please note that client side metrics \*\*exclude\*\* the server response time\.$/d' \
>> pr-meta/body.md

- name: Upload the performance report
if: ${{ steps.download-summaries.outcome == 'success' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: pr-meta--performance
path: pr-meta
if-no-files-found: ignore

- name: Publish performance results
if: github.event_name == 'push'
env:
Expand All @@ -266,3 +306,41 @@ jobs:
COMMITTED_AT="$(git show -s "$GITHUB_SHA" --format="%cI")"
REFERENCE_COMMIT="$(echo "$BRANCHES" | jq -r '.[1].name')"
node tools/release/log-performance-results.js "$CODEHEALTH_PROJECT_TOKEN" trunk "$GITHUB_SHA" "$REFERENCE_COMMIT" "$COMMITTED_AT"

pr-meta:
name: Update PR meta comment
needs: results
# Runs even when the tests failed, so a stale report is cleared.
# Skipped on a fork, whose token cannot write a comment.
if: ${{ !cancelled() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: 'ubuntu-24.04'
permissions:
contents: read
pull-requests: write
timeout-minutes: 5
# Shared with every other writer of this comment. See bundle-size.yml.
concurrency:
group: pr-meta-${{ github.event.number }}
cancel-in-progress: false
queue: max

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
sparse-checkout: tools/pr-meta
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
continue-on-error: true
with:
name: pr-meta--performance
path: pr-meta

- uses: ./tools/pr-meta
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
section: performance
body-path: pr-meta/body.md
commit-sha: ${{ github.event.pull_request.head.sha }}
run-url: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
Loading
Loading