mirror of
https://github.com/cypress-io/cypress.git
synced 2025-12-31 11:39:48 -06:00
* chore: fix get-published-artifact scripts [run ci] * update unit test, check linux-arm workflow [run ci] * circle workflow getting cached?
172 lines
4.7 KiB
JavaScript
172 lines
4.7 KiB
JavaScript
const fs = require('fs-extra')
|
|
const rp = require('@cypress/request-promise')
|
|
const util = require('util')
|
|
const exec = require('child_process').exec
|
|
const minimist = require('minimist')
|
|
const chalk = require('chalk')
|
|
|
|
const execPromise = util.promisify(exec)
|
|
|
|
const getArtifactJobName = (platformKey) => {
|
|
if (platformKey === 'linux-x64') {
|
|
return 'linux-amd-publish-binary'
|
|
}
|
|
|
|
return 'publish-binary'
|
|
}
|
|
|
|
const urlPaths = [
|
|
'~/cypress/binary-url.json',
|
|
'~/cypress/npm-package-url.json',
|
|
]
|
|
|
|
const archivePaths = [
|
|
'~/cypress/cypress.zip',
|
|
'~/cypress/cypress.tgz',
|
|
]
|
|
|
|
function getRequestOptions (url) {
|
|
return {
|
|
method: 'GET',
|
|
url,
|
|
headers: { 'Circle-Token': process.env.CIRCLE_TOKEN },
|
|
}
|
|
}
|
|
|
|
function getPipelineId (pipelineInfoFilePath) {
|
|
const data = fs.readFileSync(pipelineInfoFilePath)
|
|
|
|
const parsedPipelineId = JSON.parse(data).id
|
|
|
|
if (!parsedPipelineId) {
|
|
throw new Error(`error retrieving pipeline id from ${pipelineInfoFilePath}`)
|
|
}
|
|
|
|
return parsedPipelineId
|
|
}
|
|
|
|
async function getWorkflows (pipelineId) {
|
|
const response = await rp(getRequestOptions(`https://circleci.com/api/v2/pipeline/${pipelineId}/workflow`))
|
|
|
|
const parsed = JSON.parse(response)
|
|
|
|
if (parsed.items.length === 0) {
|
|
throw new Error(`did not find any workflows in pipeline ${pipelineId}`)
|
|
}
|
|
|
|
if (parsed.items.length > 1) {
|
|
console.log(parsed.items)
|
|
throw new Error(`expected pipeline ${pipelineId} to only have one workflow, but it had many`)
|
|
}
|
|
|
|
return parsed.items
|
|
}
|
|
|
|
async function getWorkflowJobs (workflowId) {
|
|
const response = await rp(getRequestOptions(`https://circleci.com/api/v2/workflow/${workflowId}/job`))
|
|
|
|
const parsed = JSON.parse(response)
|
|
|
|
if (parsed.items.length === 0) {
|
|
throw new Error(`did not find any jobs in workflow ${workflowId}`)
|
|
}
|
|
|
|
return parsed.items
|
|
}
|
|
|
|
async function getJobArtifacts (jobNumber) {
|
|
const response = await rp(getRequestOptions(`https://circleci.com/api/v2/project/github/cypress-io/cypress-publish-binary/${jobNumber}/artifacts`))
|
|
|
|
const parsed = JSON.parse(response)
|
|
|
|
if (parsed.items.length === 0) {
|
|
throw new Error(`did not find any artifacts for job ${jobNumber}`)
|
|
}
|
|
|
|
return parsed.items
|
|
}
|
|
|
|
async function downloadArtifact (url, path) {
|
|
try {
|
|
console.log(`Downloading artifact from ${chalk.cyan(url)} \n to path ${chalk.cyan(path)}...`)
|
|
await execPromise(`curl -L --url ${url} --header 'Circle-Token: ${process.env.CIRCLE_TOKEN}' --header 'content-type: application/json' -o ${path}`)
|
|
} catch (error) {
|
|
throw new Error(`failed to fetch artifact from URL ${url}: ${error}`)
|
|
}
|
|
}
|
|
|
|
async function run (args) {
|
|
const options = minimist(args)
|
|
|
|
const artifactJobName = getArtifactJobName(options.platformKey)
|
|
|
|
const pipelineInfoFilePath = options.pipelineInfo
|
|
|
|
if (!pipelineInfoFilePath) {
|
|
throw new Error('--pipelineInfo must be provided as a parameter')
|
|
}
|
|
|
|
console.log(`Parsing pipeline info from ${chalk.cyan(pipelineInfoFilePath)}...`)
|
|
|
|
const pipelineId = module.exports.getPipelineId(pipelineInfoFilePath)
|
|
|
|
console.log(`Getting workflows from pipeline ${chalk.cyan(pipelineId)}...`)
|
|
const workflows = await module.exports.getWorkflows(pipelineId)
|
|
|
|
const workflow = workflows[0]
|
|
|
|
if (workflow.status !== 'success') {
|
|
console.error(chalk.red(`\nThe ${chalk.cyan(workflow.name)} workflow that we triggered in the ${chalk.cyan('cypress-publish-binary')} project did not succeed.\n
|
|
Status: ${chalk.red(workflow.status)} \n
|
|
Check the workflow logs to see why it failed
|
|
|
|
${chalk.cyan.underline(`https://app.circleci.com/pipelines/workflows/${workflow.id}`)}
|
|
`))
|
|
|
|
process.exitCode = 1
|
|
|
|
return
|
|
}
|
|
|
|
console.log(`Getting jobs from workflow ${chalk.cyan(workflow.name)}...`)
|
|
const jobs = await module.exports.getWorkflowJobs(workflow.id)
|
|
|
|
const job = jobs.find((job) => job.name === artifactJobName)
|
|
|
|
if (!job) {
|
|
throw new Error(`unable to find job in workflow ${workflow.name} named ${artifactJobName}`)
|
|
}
|
|
|
|
const artifacts = await module.exports.getJobArtifacts(job.job_number)
|
|
|
|
let artifactPaths
|
|
|
|
if (process.env.SHOULD_PERSIST_ARTIFACTS) {
|
|
artifactPaths = [...urlPaths, ...archivePaths]
|
|
} else {
|
|
// If we didn't persist the artifacts to the registry, then we only want the build artifacts, no URLs.
|
|
artifactPaths = [...archivePaths]
|
|
}
|
|
|
|
const filteredArtifacts = artifacts.filter((artifact) => artifactPaths.includes(artifact.path))
|
|
|
|
await Promise.all(filteredArtifacts.map(({ url, path }) => {
|
|
return module.exports.downloadArtifact(url, path)
|
|
}))
|
|
|
|
console.log('Artifacts successfully downloaded ✅')
|
|
}
|
|
|
|
module.exports = {
|
|
getPipelineId,
|
|
getWorkflows,
|
|
getWorkflowJobs,
|
|
getJobArtifacts,
|
|
downloadArtifact,
|
|
run,
|
|
}
|
|
|
|
if (!module.parent) {
|
|
run(process.argv)
|
|
}
|