Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#62221 GitHub Actions workflow hardening #8007

Draft
wants to merge 23 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
2e87b77
Use existing environment variables in place of GitHub Actions express…
johnbillion Dec 9, 2024
39026ab
Make more use of environment variables in JavaScript steps.
johnbillion Dec 9, 2024
1d1ee67
Prevent breaking out of environment variable assignment.
johnbillion Dec 9, 2024
878b800
Prevent breaking out of command arguments.
johnbillion Dec 9, 2024
b2ace91
Remove a redundant step.
johnbillion Dec 9, 2024
47ba701
Use an environment variable in this JavaScript step.
johnbillion Dec 9, 2024
fc746fb
Clearer formatting for these dynamic command arguments.
johnbillion Dec 9, 2024
5548281
Replace manual construction of JSON with safe output from `jq`.
johnbillion Dec 9, 2024
c0c49a1
Break this long line into multiple lines for clarity and replace GitH…
johnbillion Dec 9, 2024
1143dca
Replace some more logic with environment variables.
johnbillion Dec 9, 2024
896fee1
More formatting for readability.
johnbillion Dec 10, 2024
32146c2
Replace more GitHub Actions expressions with environment variables.
johnbillion Dec 10, 2024
e869cb8
Disable permissions for all available scopes by default.
johnbillion Dec 16, 2024
5ea1b0d
Add a linting workflow while we continue working on workflow hardening.
johnbillion Dec 16, 2024
9a6c833
Correct this flag.
johnbillion Dec 16, 2024
127221a
None of the checkouts need credentials to be persisted.
johnbillion Dec 16, 2024
7f038d8
Disable false positive shellcheck errors for these `jq` inputs.
johnbillion Dec 16, 2024
8b78bb1
Fix a syntax error.
johnbillion Dec 16, 2024
b5c6517
Pretty sure this isn't needed.
johnbillion Dec 16, 2024
4727f52
Quote all the GitHub file paths.
johnbillion Dec 16, 2024
02d49e2
This isn't needed.
johnbillion Dec 16, 2024
7a00926
Disable shellcheck in Actionlint as it gets duplicated in Octoscan.
johnbillion Dec 16, 2024
150c8c2
Fix this up.
johnbillion Dec 16, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/coding-standards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,6 @@ jobs:
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
run_id: context.runId,
}
});
2 changes: 1 addition & 1 deletion .github/workflows/end-to-end-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,6 @@ jobs:
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
run_id: context.runId,
}
});
6 changes: 4 additions & 2 deletions .github/workflows/failed-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
const workflow_run = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ inputs.run_id }},
run_id: process.env.RUN_ID,
});

// Only rerun after the first run attempt.
Expand All @@ -49,6 +49,8 @@ jobs:
const rerun = await github.rest.actions.reRunWorkflowFailedJobs({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ inputs.run_id }},
run_id: process.env.RUN_ID,
enable_debug_logging: true
});
env:
RUN_ID: ${{ inputs.run_id }}
18 changes: 12 additions & 6 deletions .github/workflows/install-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
--health-retries="5"
-e MYSQL_ROOT_PASSWORD="root"
-e MYSQL_DATABASE="test_db"
--entrypoint sh ${{ matrix.db-type }}:${{ matrix.db-version }}
--entrypoint sh
-c "exec docker-entrypoint.sh mysqld${{ matrix.db-type == 'mysql' && contains( fromJSON('["7.2", "7.3"]'), matrix.php ) && ' --default-authentication-plugin=mysql_native_password' || '' }}"

steps:
Expand All @@ -113,16 +113,22 @@ jobs:
with:
php-version: '${{ matrix.php }}'
coverage: none
tools: wp-cli${{ contains( fromJSON('["5.4", "5.5"]'), matrix.php ) && ':2.4.0' || '' }}
tools: ${{ contains( fromJSON('["5.4", "5.5"]'), matrix.php ) && 'wp-cli:2.4.0' || 'wp-cli' }}

- name: Download WordPress
run: wp core download ${{ inputs.wp-version && format( '--version={0}', inputs.wp-version ) || '--version=nightly' }}
run: |
wp core download \
${{ inputs.wp-version && '--version="${WP_VERSION}"' || '--version=nightly' }}
env:
WP_VERSION: ${{ inputs.wp-version }}

- name: Create wp-config.php file
run: wp config create --dbname=test_db --dbuser=root --dbpass=root --dbhost=127.0.0.1:${{ job.services.database.ports['3306'] }}
run: wp config create --dbname=test_db --dbuser=root --dbpass=root --dbhost="127.0.0.1:${DB_PORT}"
env:
DB_PORT: ${{ job.services.database.ports['3306'] }}

- name: Install WordPress
run: wp core ${{ matrix.multisite && 'multisite-' || '' }}install --url=http://localhost/ --title="Upgrade Test" --admin_user=admin --admin_password=password [email protected] --skip-email
run: wp core ${{ matrix.multisite && 'multisite-install' || 'install' }} --url=http://localhost/ --title="Upgrade Test" --admin_user=admin --admin_password=password [email protected] --skip-email

slack-notifications:
name: Slack Notifications
Expand Down Expand Up @@ -169,6 +175,6 @@ jobs:
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
run_id: context.runId,
}
});
2 changes: 1 addition & 1 deletion .github/workflows/javascript-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,6 @@ jobs:
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
run_id: context.runId,
}
});
105 changes: 105 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Lint GitHub Actions

on:
push:
branches:
- trunk
- '[0-9].[0-9]'
tags:
- '[0-9]+.[0-9]'
- '[0-9]+.[0-9].[0-9]+'
paths:
# Only run when changes are made to workflow files.
- '.github/workflows/**'
pull_request:
branches:
- trunk
- '[0-9].[0-9]'
paths:
# Only run when changes are made to workflow files.
- '.github/workflows/**'
workflow_dispatch:

# Cancels all previous workflow runs for pull requests that have not completed.
concurrency:
# The concurrency group contains the workflow name and the branch name for pull requests
# or the commit hash for any other events.
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }}
cancel-in-progress: true

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

jobs:
actionlint:
name: Actionlint
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 5
steps:
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
persist-credentials: false

- name: Run actionlint
uses: docker://rhysd/actionlint:1.7.4
with:
args: "-color -verbose -shellcheck="

octoscan:
name: Octoscan
runs-on: ubuntu-24.04
permissions:
contents: read
timeout-minutes: 10
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Checkout Octoscan
uses: actions/checkout@v4
with:
repository: synacktiv/octoscan
path: octoscan
persist-credentials: false

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.21'

- name: Install and build Octoscan
run: | #shell
cd octoscan
go mod tidy
go build

- name: Run Octoscan
run: | #shell
./octoscan/octoscan scan .

zizmor:
name: Zizmor
runs-on: ubuntu-24.04
permissions:
security-events: write
actions: read
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install the latest version of uv
uses: astral-sh/setup-uv@v4

- name: Run zizmor
run: uvx zizmor .
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/local-docker-environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,6 @@ jobs:
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
run_id: context.runId,
}
});
2 changes: 1 addition & 1 deletion .github/workflows/performance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,6 @@ jobs:
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
run_id: context.runId,
}
});
2 changes: 1 addition & 1 deletion .github/workflows/php-compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ jobs:
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
run_id: context.runId,
}
});
2 changes: 1 addition & 1 deletion .github/workflows/phpunit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,6 @@ jobs:
workflow_id: 'failed-workflow.yml',
ref: 'trunk',
inputs: {
run_id: '${{ github.run_id }}'
run_id: context.runId,
}
});
4 changes: 3 additions & 1 deletion .github/workflows/props-bot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ jobs:
github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: '${{ github.event.number }}',
issue_number: process.env.ISSUE_NUMBER,
name: 'props-bot'
});
env:
ISSUE_NUMBER: ${{ github.event.number }}
4 changes: 3 additions & 1 deletion .github/workflows/pull-request-comments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ jobs:
const artifacts = await github.rest.actions.listWorkflowRunArtifacts( {
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{ github.event.workflow_run.id }},
run_id: process.env.RUN_ID,
} );

const matchArtifact = artifacts.data.artifacts.filter( ( artifact ) => {
Expand All @@ -117,6 +117,8 @@ jobs:

const fs = require( 'fs' );
fs.writeFileSync( '${{github.workspace}}/pr-number.zip', Buffer.from( download.data ) )
env:
RUN_ID: ${{ github.event.workflow_run.id }}

- name: Unzip the artifact containing the PR number
run: unzip pr-number.zip
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/reusable-coding-standards-javascript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ on:
env:
PUPPETEER_SKIP_DOWNLOAD: ${{ true }}

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

jobs:
# Runs the JavaScript coding standards checks.
#
Expand All @@ -33,6 +37,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Set up Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/reusable-coding-standards-php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ on:
type: 'boolean'
default: false

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

jobs:
# Runs the PHP coding standards checks.
#
Expand Down Expand Up @@ -45,6 +49,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Set up PHP
uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 # v2.31.1
Expand All @@ -57,7 +62,7 @@ jobs:
# http://man7.org/linux/man-pages/man1/date.1.html
- name: "Get last Monday's date"
id: get-date
run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> $GITHUB_OUTPUT
run: echo date="$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT"

- name: Cache PHPCS scan cache
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2
Expand All @@ -75,7 +80,7 @@ jobs:
custom-cache-suffix: ${{ steps.get-date.outputs.date }}

- name: Make Composer packages available globally
run: echo "${PWD}/vendor/bin" >> $GITHUB_PATH
run: echo "${PWD}/vendor/bin" >> "$GITHUB_PATH"

- name: Run PHPCS on all Core files
id: phpcs-core
Expand Down
22 changes: 16 additions & 6 deletions .github/workflows/reusable-end-to-end-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ env:
LOCAL_DIR: build
LOCAL_PHP: ${{ inputs.php-version }}${{ 'latest' != inputs.php-version && '-fpm' || '' }}

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

jobs:
# Runs the end-to-end test suite.
#
Expand Down Expand Up @@ -63,13 +67,14 @@ jobs:
steps:
- name: Configure environment variables
run: |
echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV
echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV
echo PHP_FPM_UID="$(id -u)" >> "$GITHUB_PATH"
echo PHP_FPM_GID="$(id -g)" >> "$GITHUB_ENV"

- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Set up Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
Expand Down Expand Up @@ -117,13 +122,18 @@ jobs:

- name: Install Gutenberg
if: ${{ inputs.install-gutenberg }}
run: npm run env:cli -- plugin install gutenberg${{ inputs.gutenberg-version && format( ' --version={0}', inputs.gutenberg-version ) || '' }} --path=/var/www/${{ env.LOCAL_DIR }}
run: |
npm run env:cli -- plugin install gutenberg \
${{ inputs.gutenberg-version && '--version="${GUTENBERG_VERSION}"' || '' }} \
--path="/var/www/${LOCAL_DIR}"
env:
GUTENBERG_VERSION: ${{ inputs.gutenberg-version }}

- name: Install additional languages
run: |
npm run env:cli -- language core install de_DE --path=/var/www/${{ env.LOCAL_DIR }}
npm run env:cli -- language plugin install de_DE --all --path=/var/www/${{ env.LOCAL_DIR }}
npm run env:cli -- language theme install de_DE --all --path=/var/www/${{ env.LOCAL_DIR }}
npm run env:cli -- language core install de_DE --path="/var/www/${LOCAL_DIR}"
npm run env:cli -- language plugin install de_DE --all --path="/var/www/${LOCAL_DIR}"
npm run env:cli -- language theme install de_DE --all --path="/var/www/${LOCAL_DIR}"

- name: Run E2E tests
run: npm run test:e2e
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/reusable-javascript-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ name: JavaScript tests
on:
workflow_call:

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

jobs:
# Runs the QUnit test suite.
#
Expand All @@ -28,6 +32,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Set up Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
Expand Down
Loading
Loading