Skip to content

Make Pixel smarter about needed Codex version (WIP) #329

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
63 changes: 52 additions & 11 deletions pixel.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,34 @@ async function getLatestCodexVersion() {
return `${stdout.split( 'refs/tags/' )[ 1 ].trim()}`;
}

/**
* @param {string} mwBranch
* @return {Promise<string>}
*/
async function getCodexVersionForMWBranch( mwBranch ) {
// Get the version referenced in the MW branch's 'foreign-resources.yaml'
// First remove the remote prefix from the branch, if present
// So "origin/wmf/1.43.0-wmf.5" becomes "wmf/1.43.0-wmf.5"
mwBranch = ( mwBranch.match( /\//g ) || [] ).length > 1 ?
mwBranch.slice( mwBranch.indexOf( '/' ) + 1 ) :
mwBranch;
try {
const { stdout } = await exec( `
curl -sf --compressed --retry 5 --retry-delay 5 --retry-max-time 120 'https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/core/+/refs/heads/${mwBranch}/resources/lib/foreign-resources.yaml?format=TEXT' | \
docker run --rm -i mikefarah/yq eval '@base64d | from_yaml | .codex.version' -
` );
if ( stdout.trim() === '' ) {
throw new Error( 'Codex version string is unexpectedly blank' );
}
return `v${stdout.trim()}`;
} catch ( error ) {
error.message = "Error getting Codex version for MW branch '" + mwBranch + "'\n" +
error.message +
"Either 'foreign-resources.yaml' doesn't exist at the curled url, couldn't be retrieved, or the yaml key '.codex.version' is not present in that version of the yaml\n";
throw error;
}
}

/**
* @param {string} indexFileFullPath Full path to the index file.
* @param {string} bannerContent The banner content to prepend.
Expand Down Expand Up @@ -134,6 +162,23 @@ function removeFolder( relativePath ) {
fs.rmSync( `${__dirname}/${relativePath}`, { recursive: true, force: true } );
}

async function updateCodexRepoBranchIfNecessary( opts, mwBranch ) {
// Return if the user has already specified a '--repo-branch' for Codex
if ( opts.repoBranch?.some( ( branch ) => branch.startsWith( 'design/codex:' ) ) ) {
return;
}
// Determine which Codex version the MW branch wants and use it,
// fallback on latest version
let codexVersion;
try {
codexVersion = await getCodexVersionForMWBranch( mwBranch );
} catch ( error ) {
codexVersion = await getLatestCodexVersion();
console.log( `\x1b[33m${error.message}Falling back to latest Codex version ${codexVersion}\x1b[0m` );
}
opts.repoBranch = [ ...( opts.repoBranch ?? [] ), `design/codex:${codexVersion}` ];
}

/**
* @typedef {Object} CommandOptions
* @property {string[]} [changeId]
Expand All @@ -155,9 +200,12 @@ async function processCommand( type, opts, runSilently = false ) {

setEnvironmentFlagIfGroup( 'ENABLE_WIKILAMBDA', 'wikilambda', group );

const activeBranch = await getActiveBranch( opts );
const activeMWBranch = await getActiveBranch( opts );

await updateCodexRepoBranchIfNecessary( opts, activeMWBranch );

const description = getDescription( opts );
updateContext( group, type, activeBranch, description );
updateContext( group, type, activeMWBranch, description );

await prepareDockerEnvironment( opts );
const { stdout: stdout1 } = await simpleSpawn.exec( './purgeParserCache.sh' );
Expand All @@ -181,22 +229,15 @@ async function processCommand( type, opts, runSilently = false ) {

async function getActiveBranch( opts ) {
if ( opts.branch === LATEST_RELEASE_BRANCH ) {
return await getLatestReleaseBranchAndUpdateOpts( opts );
opts.branch = await getLatestReleaseBranch();
return opts.branch;
} else if ( opts.branch !== 'master' ) {
return opts.branch;
} else {
return opts.changeId ? opts.changeId[ 0 ] : opts.branch;
}
}

async function getLatestReleaseBranchAndUpdateOpts( opts ) {
opts.branch = await getLatestReleaseBranch();
const codexTag = await getLatestCodexVersion();
opts.repoBranch = [ ...( opts.repoBranch ?? [] ), `design/codex:${codexTag}` ];
console.log( `Using latest branch "${opts.branch}" (for Codex, "${codexTag}")` );
return opts.branch;
}

function getDescription( opts ) {
let description = '';

Expand Down
Loading