Skip to content

Commit 2e8d730

Browse files
committed
Build/Test Tools: Improve certificate-related build scripts.
Because an exact version is pinned for `composer/ca-bundle`, the `composer update` command cannot update the dependency to the latest version. The command also does not work for a single dependency due to the fact that Composer has been configured not to generate a `composer.lock` file. This updates the Grunt task to determine the new version using `composer outdated` before running `composer require composer/ca-bundle:NEW_VERSION --dev` to properly update the pinned version. This also updates the build process test workflow to confirm that the certificate-related files under version control in `src/wp-includes/certificates` are up to date. Props johnbillion. Fixes #63939. git-svn-id: https://develop.svn.wordpress.org/trunk@60765 602fd350-edb4-49c9-b593-d223f7449a82
1 parent c01d627 commit 2e8d730

File tree

3 files changed

+90
-4
lines changed

3 files changed

+90
-4
lines changed

.github/workflows/reusable-test-core-build-process.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ on:
1717
type: 'string'
1818
default: 'src'
1919
test-emoji:
20-
description: 'Whether to run the grunt precommit:emoji script.'
20+
description: 'Whether to run the precommit:emoji Grunt script.'
2121
required: false
2222
type: 'boolean'
2323
default: true
24+
test-certificates:
25+
description: 'Whether to run the certificate related Grunt scripts.'
26+
required: false
27+
type: 'boolean'
28+
default: false
2429
save-build:
2530
description: 'Whether to save a ZIP of built WordPress as an artifact.'
2631
required: false
@@ -69,6 +74,21 @@ jobs:
6974
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
7075
persist-credentials: false
7176

77+
# This date is used to ensure that the PHPCS cache is cleared at least once every week.
78+
# http://man7.org/linux/man-pages/man1/date.1.html
79+
- name: "Get last Monday's date"
80+
id: get-date
81+
if: ${{ inputs.test-certificates }}
82+
run: echo "date=$(/bin/date -u --date='last Mon' "+%F")" >> "$GITHUB_OUTPUT"
83+
84+
# Since Composer dependencies are installed using `composer update` and no lock file is in version control,
85+
# passing a custom cache suffix ensures that the cache is flushed at least once per week.
86+
- name: Install Composer dependencies
87+
if: ${{ inputs.test-certificates }}
88+
uses: ramsey/composer-install@3cf229dc2919194e9e36783941438d17239e8520 # v3.1.1
89+
with:
90+
custom-cache-suffix: ${{ steps.get-date.outputs.date }}
91+
7292
- name: Set up Node.js
7393
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
7494
with:
@@ -91,6 +111,10 @@ jobs:
91111
env:
92112
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
93113

114+
- name: Ensure certificates files are updated
115+
if: ${{ inputs.test-certificates }}
116+
run: npm run grunt copy:certificates && npm run grunt build:certificates
117+
94118
- name: Build WordPress to run from ${{ inputs.directory }}
95119
run: npm run ${{ inputs.directory == 'src' && 'build:dev' || 'build' }}
96120

.github/workflows/test-build-processes.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ jobs:
5959
matrix:
6060
os: [ 'ubuntu-24.04' ]
6161
directory: [ 'src', 'build' ]
62+
test-certificates: [ true ]
6263
include:
6364
# Only prepare artifacts for Playground once.
6465
- os: 'ubuntu-24.04'
@@ -68,6 +69,7 @@ jobs:
6869
with:
6970
os: ${{ matrix.os }}
7071
directory: ${{ matrix.directory }}
72+
test-certificates: ${{ matrix.test-certificates && true || false }}
7173
save-build: ${{ matrix.save-build && matrix.save-build || false }}
7274
prepare-playground: ${{ matrix.prepare-playground && matrix.prepare-playground || false }}
7375

Gruntfile.js

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,10 +1584,69 @@ module.exports = function(grunt) {
15841584
'usebanner'
15851585
] );
15861586

1587-
grunt.registerTask( 'certificates:update', 'Updates the Composer package responsible for root certificate updates.', function() {
1587+
grunt.registerTask( 'certificates:upgrade-package', 'Upgrades the package responsible for supplying the certificate authority certificate store bundled with WordPress.', function() {
15881588
var done = this.async();
15891589
var flags = this.flags;
1590-
var args = [ 'update' ];
1590+
var spawn = require( 'child_process' ).spawnSync;
1591+
var fs = require( 'fs' );
1592+
1593+
// Ensure that `composer update` has been run and the dependency is installed.
1594+
if ( ! fs.existsSync( 'vendor' ) || ! fs.existsSync( 'vendor/composer' ) || ! fs.existsSync( 'vendor/composer/ca-bundle' ) ) {
1595+
grunt.log.error( 'composer/ca-bundle dependency is missing. Please run `composer update` before attempting to upgrade the certificate bundle.' );
1596+
done( false );
1597+
return;
1598+
}
1599+
1600+
/*
1601+
* Because the `composer/ca-bundle` is pinned to an exact version to ensure upgrades are applied intentionally,
1602+
* the `composer update` command will not upgrade the dependency. Instead, `composer require` must be called,
1603+
* but the specific version being upgraded to must be known and passed to the command.
1604+
*/
1605+
var outdatedResult = spawn( 'composer', [ 'outdated', 'composer/ca-bundle', '--format=json' ] );
1606+
1607+
if ( outdatedResult.status !== 0 ) {
1608+
grunt.log.error( 'Failed to get the package information for composer/ca-bundle.' );
1609+
done( false );
1610+
return;
1611+
}
1612+
1613+
var packageInfo;
1614+
try {
1615+
var stdout = outdatedResult.stdout.toString().trim();
1616+
if ( ! stdout ) {
1617+
grunt.log.writeln( 'The latest version is already installed.' );
1618+
done( true );
1619+
return;
1620+
}
1621+
packageInfo = JSON.parse( stdout );
1622+
} catch ( e ) {
1623+
grunt.log.error( 'Failed to parse the package information for composer/ca-bundle.' );
1624+
done( false );
1625+
return;
1626+
}
1627+
1628+
// Check for the version information needed to perform the necessary comparisons.
1629+
if ( ! packageInfo.versions || ! packageInfo.versions[0] || ! packageInfo.latest ) {
1630+
grunt.log.error( 'Could not determine version information for composer/ca-bundle.' );
1631+
done( false );
1632+
return;
1633+
}
1634+
1635+
var currentVersion = packageInfo.versions[0];
1636+
var latestVersion = packageInfo.latest;
1637+
1638+
// Compare versions to ensure we actually need to update
1639+
if ( currentVersion === latestVersion ) {
1640+
grunt.log.writeln( 'The latest version is already installed: ' + latestVersion + '.' );
1641+
done( true );
1642+
return;
1643+
}
1644+
1645+
grunt.log.writeln( 'Installed version: ' + currentVersion );
1646+
grunt.log.writeln( 'New version found: ' + latestVersion );
1647+
1648+
// Upgrade to the latest version and change the pinned version in composer.json.
1649+
var args = [ 'require', 'composer/ca-bundle:' + latestVersion, '--dev' ];
15911650

15921651
grunt.util.spawn( {
15931652
cmd: 'composer',
@@ -1597,6 +1656,7 @@ module.exports = function(grunt) {
15971656
if ( flags.error && error ) {
15981657
done( false );
15991658
} else {
1659+
grunt.log.writeln( 'Successfully updated composer/ca-bundle to ' + latestVersion );
16001660
done( true );
16011661
}
16021662
} );
@@ -1607,7 +1667,7 @@ module.exports = function(grunt) {
16071667
] );
16081668

16091669
grunt.registerTask( 'certificates:upgrade', [
1610-
'certificates:update',
1670+
'certificates:upgrade-package',
16111671
'copy:certificates',
16121672
'build:certificates'
16131673
] );

0 commit comments

Comments
 (0)