Skip to content

Instantly share code, notes, and snippets.

@KwanEsq
Last active June 27, 2023 19:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save KwanEsq/0959333d8c8781f6582fe3988af4d483 to your computer and use it in GitHub Desktop.
Save KwanEsq/0959333d8c8781f6582fe3988af4d483 to your computer and use it in GitHub Desktop.
Update Unbranded links
// ==UserScript==
// @name Unbranded build update
// @version 4
// @grant none
// @match https://wiki.mozilla.org/index.php?title=Add-ons/Extension_Signing&action=edit&section=6*
// ==/UserScript==
async function getUnbranded(revision, version, channel) {
const builds = [
{
platform: 'Linux',
type_name: 'build-linux64-add-on-devel%2Fopt',
artifact_name: 'target.tar.bz2',
},
{
platform: 'Mac OSX',
type_name: 'build-macosx64-add-on-devel%2Fopt',
artifact_name: 'target.dmg',
},
{
platform: 'Windows 32-bit',
type_name: 'build-win32-add-on-devel%2Fopt',
artifact_name: 'target.zip',
},
{
platform: 'Windows 64-bit',
type_name: 'build-win64-add-on-devel%2Fopt',
artifact_name: 'target.zip',
},
];
const headers = new Headers({ 'Content-Type': 'application/json' });
// get the ID of the result set for the push
const idQuery = await fetch(
`https://treeherder.mozilla.org/api/project/mozilla-${channel}/push/` +
`?revision=${revision}`,
{ headers }
);
const id = (await idQuery.json()).results[0].id;
const results = {};
for (const { platform, type_name, artifact_name } of builds) {
// get the ids for the build job
const idQuery = await fetch(
`https://treeherder.mozilla.org/api/project/mozilla-${channel}/jobs/` +
`?result_set_id=${id}&job_type_name=${type_name}`,
{ headers },
);
const idResults = (await idQuery.json()).results;
// there might be retries before the actual result
const successId = idResults.find(result => result.result === 'success');
if (!successId) {
results[platform] = false;
continue;
}
const { task_id, retry_id } = successId;
const tcUrl =
`https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/${task_id}/runs/${retry_id}/artifacts`;
// get all the artifacts from the job
const artifactsQuery = await fetch(
tcUrl,
{ headers },
);
const artifacts = await artifactsQuery.json();
// get the URL for the installer artifact
for (const artifact of artifacts.artifacts) {
if (artifact.name.endsWith(artifact_name)) {
const url = `${tcUrl}/${artifact.name}`;
results[platform] = url;
break;
}
}
}
const shortRev = revision.substr(0, 12);
const output = `Latest ${channel} (Firefox ${version} - [https://hg.mozilla` +
`.org/releases/mozilla-${channel}/rev/${shortRev} changeset ${shortRev}]) builds:
${Object.entries(results).map(([k, v]) => !v ? `* No ${k} builds available due to [https://bugzilla.mozilla.org/show_bug.cgi?id=### bug ###]` : `* [${v} ${k}]`).join('\n')}`;
return output;
}
async function updateUnbranded() {
const button = document.getElementById('unbranded-update');
button.classList.add('running');
const textbox = document.getElementById('wpTextbox1');
const wikiBeta = textbox.value.match(/Latest beta \(Firefox ([\db\.]+)/)[1];
const wikiRelease = textbox.value.match(/Latest release \(Firefox ([\d\.]+)/)[1];
const versionQuery =
await fetch('https://product-details.mozilla.org/1.0/firefox_versions.json');
const versions = await versionQuery.json();
const currentBeta = versions.LATEST_FIREFOX_RELEASED_DEVEL_VERSION;
const currentRelease = versions.LATEST_FIREFOX_VERSION;
function insertResult(result, start, end) {
const beforeText = textbox.value.slice(0, start);
const afterText = textbox.value.slice(end);
textbox.value = beforeText + result + afterText;
}
const updated = [];
// only get builds if the version isn't the same as the mentioned one
if (wikiRelease !== currentRelease) {
button.title = 'Found release update. Fetching artifacts';
const hgQuery =
await fetch(
'https://hg.mozilla.org/releases/mozilla-release/json-log?rev=FIREFOX_' +
`${currentRelease.replace(/\./g, '_')}_RELEASE`
);
const hash = (await hgQuery.json()).entries[0].node;
try {
const result = await getUnbranded(hash, currentRelease, 'release');
const start = textbox.value.indexOf('Latest release');
const end = textbox.value.indexOf("\n\n'''Beta");
insertResult(result, start, end);
updated.push(currentRelease);
} catch (e) {
alert(`Failed to fetch release builds ${e}`);
}
}
if (wikiBeta !== currentBeta) {
button.title = 'Found beta update. Fetching artifacts';
const hgQuery =
await fetch(
'https://hg.mozilla.org/releases/mozilla-beta/json-log?rev=FIREFOX_' +
`${currentBeta.replace(/\./g, '_')}_RELEASE`
);
const hash = (await hgQuery.json()).entries[0].node;
try {
const result = await getUnbranded(hash, currentBeta, 'beta');
const start = textbox.value.indexOf('Latest beta');
const end = textbox.value.length;
insertResult(result, start, end);
updated.push(currentBeta);
} catch (e) {
alert(`Failed to fetch beta builds ${e}`);
}
}
button.title = 'Updated';
if (updated.length > 0) {
document.getElementById('wpSummary').value +=
'Updated for ' + updated.join(' and ');
}
button.classList.remove('running');
}
function createUI() {
const insertPoint = document.querySelector('#wikiEditor-section-advanced > .group-insert');
if (!insertPoint) {
return;
}
clearInterval(timer);
const styles = [
`.wikiEditor-ui-toolbar .group-insert {
border-right: 1px solid #ddd !important;
}`,
`.wikiEditor-ui-toolbar .group-unbranded {
border-right: none;
}`,
`#unbranded-update {
cursor: pointer;
}`,
`#unbranded-update.running {
cursor: wait;
}`,
];
const container = document.createElement('div');
container.classList.add('group', 'group-unbranded');
container.setAttribute('rel', 'unbranded');
const label = document.createElement('span');
label.classList.add('label');
label.textContent = 'Unbranded';
const update = document.createElement('a');
update.id = 'unbranded-update';
update.classList.add('tool');
update.setAttribute('rel', 'update');
update.setAttribute('role', 'button');
update.title = update.textContent = 'Update';
update.addEventListener('click', updateUnbranded);
container.append(label, update);
insertPoint.after(container);
for (const style of styles) {
document.styleSheets[1].insertRule(style);
}
}
var timer = setInterval(createUI, 500);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment