Files
react-native/scripts/release-testing/utils/github-actions-utils.js
T
Riccardo Cipolleschi 27bd6c9227 Use Debug APK for release testing (#46413)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46413

When testing RNTester for Android during a release, we downloads the APKs from CI to save time.

Sadly, we were downloading the Release APKs instead of the Debug ones, so we could not test te integration with Metro.

This change fixes the testing scripts to download the debug APK

## Changelog
[Internal] - Download the debug APK instead of the Release one

Reviewed By: cortinico

Differential Revision: D62436023

fbshipit-source-id: 08a568caf3e5c85b9da933bc01623587bd36affe
2024-09-10 04:41:07 -07:00

211 lines
5.0 KiB
JavaScript

#!/usr/bin/env node
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
const {execSync: exec} = require('child_process');
const fetch = require('node-fetch');
/*::
type CIHeaders = {
Authorization: string,
Accept: string,
'X-GitHub-Api-Version': string
}
type WorkflowRun = {
id: number,
name: string,
run_number: number,
status: string,
workflow_id: number,
url: string,
created_at: string,
};
type Artifact = {
id: number,
name: string,
url: string,
archive_download_url: string,
}
type WorkflowRuns = {
total_count: number,
workflow_runs: Array<WorkflowRun>,
}
type Artifacts = {
total_count: number,
artifacts: Array<Artifact>,
}
*/
let token;
let ciHeaders;
let artifacts;
let branch;
let baseTemporaryPath;
const reactNativeRepo = 'https://api.github.com/repos/facebook/react-native/';
const reactNativeActionsURL = `${reactNativeRepo}actions/runs`;
async function _getActionRunsOnBranch() /*: Promise<WorkflowRuns> */ {
const url = `${reactNativeActionsURL}?branch=${branch}&per_page=100`;
const options = {
method: 'GET',
headers: ciHeaders,
};
// $FlowIgnore[prop-missing] Conflicting .flowconfig in Meta's monorepo
// $FlowIgnore[incompatible-call]
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(JSON.stringify(await response.json()));
}
const body = await response
// eslint-disable-next-line func-call-spacing
.json /*::<WorkflowRuns>*/
();
return body;
}
async function _getArtifacts(run_id /*: number */) /*: Promise<Artifacts> */ {
const url = `${reactNativeActionsURL}/${run_id}/artifacts?per_page=100`;
const options = {
method: 'GET',
headers: ciHeaders,
};
// $FlowIgnore[prop-missing] Conflicting .flowconfig in Meta's monorepo
// $FlowIgnore[incompatible-call]
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(JSON.stringify(await response.json()));
}
const body = await response
// eslint-disable-next-line func-call-spacing
.json /*::<Artifacts>*/
();
return body;
}
// === Public Interface === //
async function initialize(
ciToken /*: string */,
baseTempPath /*: string */,
branchName /*: string */,
useLastSuccessfulPipeline /*: boolean */ = false,
) {
console.info('Getting GHA information');
baseTemporaryPath = baseTempPath;
exec(`mkdir -p ${baseTemporaryPath}`);
branch = branchName;
token = ciToken;
ciHeaders = {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
};
const testAllWorkflows = (await _getActionRunsOnBranch()).workflow_runs
.filter(w => w.name === 'Test All')
.sort((a, b) => {
// Date.getTime is needed to make Flow happy with arithmetic
return (
new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
);
});
if (testAllWorkflows.length === 0) {
console.error('No Test-All workflow found');
process.exit(1);
}
console.log(`\nUsing github workflow run ${testAllWorkflows[0].run_number}`);
console.log(
`https://github.com/facebook/react-native/actions/runs/${testAllWorkflows[0].id}\n`,
);
artifacts = await _getArtifacts(testAllWorkflows[0].id);
}
function downloadArtifact(
artifactURL /*: string */,
destination /*: string */,
) {
exec(`rm -rf ${destination}`);
const command = `curl ${artifactURL} \
-Lo ${destination} \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${token}" \
-H "X-GitHub-Api-Version: 2022-11-28"`;
exec(command, {stdio: 'inherit'});
}
async function artifactURLForJSCRNTesterAPK(
emulatorArch /*: string */,
) /*: Promise<string> */ {
return getArtifactURL('rntester-jsc-debug');
}
async function artifactURLForHermesRNTesterAPK(
emulatorArch /*: string */,
) /*: Promise<string> */ {
return getArtifactURL('rntester-hermes-debug');
}
async function artifactURLForMavenLocal() /*: Promise<string> */ {
return getArtifactURL('maven-local');
}
async function getArtifactURL(
artifactName /*: string */,
) /*: Promise<string> */ {
const filteredUrls = artifacts.artifacts.filter(a => a.name === artifactName);
if (filteredUrls.length === 0) {
console.error(`No artifact found with name ${artifactName}`);
process.exit(1);
}
return filteredUrls[0].archive_download_url;
}
async function artifactURLHermesDebug() /*: Promise<string> */ {
return getArtifactURL('hermes-darwin-bin-Debug');
}
async function artifactURLForReactNative() /*: Promise<string> */ {
return getArtifactURL('react-native-package');
}
function baseTmpPath() /*: string */ {
return baseTemporaryPath;
}
module.exports = {
initialize,
downloadArtifact,
artifactURLForJSCRNTesterAPK,
artifactURLForHermesRNTesterAPK,
artifactURLForMavenLocal,
artifactURLHermesDebug,
artifactURLForReactNative,
baseTmpPath,
};