123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- import fetch from 'node-fetch'
- import { spawnSync } from 'node:child_process'
- import prompts from 'prompts'
- import { TARGET_BRANCH, REPO_NAME, REPO_OWNER } from './config.js'
- async function apiCall (endpoint, errorMessage) {
- const response = await fetch(
- `https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}${endpoint}`,
- )
- if (response.ok) {
- return response.json()
- }
- console.warn(response)
- throw new Error(errorMessage)
- }
- export async function getRemoteHEAD () {
- return (
- await apiCall(
- `/git/ref/heads/${TARGET_BRANCH}`,
- 'Cannot get remote HEAD, check your internet connection.',
- )
- ).object.sha
- }
- async function getLatestReleaseSHA () {
- const response = await fetch(`https://raw.githubusercontent.com/${REPO_OWNER}/${REPO_NAME}/${TARGET_BRANCH}/packages/uppy/package.json`)
- if (!response.ok) throw new Error(`Network call failed: ${response.status} ${response.statusText}`)
- const { version } = await response.json()
- const tag_name = `uppy@${version}`
- console.log(`Last release was ${tag_name}.`)
- return (
- await apiCall(
- `/git/ref/tags/${encodeURIComponent(tag_name)}`,
- `Failed to fetch information for release ${JSON.stringify(tag_name)}`,
- )
- ).object.sha
- }
- async function getLocalHEAD () {
- return spawnSync('git', ['rev-parse', 'HEAD']).stdout.toString().trim()
- }
- export function rewindGitHistory (spawnOptions, sha) {
- return spawnSync('git', ['reset', sha, '--hard'], spawnOptions).status === 0
- }
- export async function validateGitStatus (spawnOptions) {
- const latestRelease = getLatestReleaseSHA() // run in parallel to speed things up
- const [REMOTE_HEAD, LOCAL_HEAD] = await Promise.all([getRemoteHEAD(), getLocalHEAD()])
- const { status, stderr } = spawnSync(
- 'git',
- ['diff', '--exit-code', '--quiet', REMOTE_HEAD, '--', '.'],
- spawnOptions,
- )
- if (status !== 0) {
- console.error(stderr.toString())
- console.log(
- `git repository is not clean and/or not in sync with ${REPO_OWNER}/${REPO_NAME}`,
- )
- if (spawnSync(
- 'git',
- ['diff', '--exit-code', '--quiet', LOCAL_HEAD, '--', '.'],
- spawnOptions,
- ).status !== 0) {
- const { value } = await prompts({
- type: 'confirm',
- name: 'value',
- message:
- 'Do you want to hard reset your local repository (all uncommitted changes will be lost)?',
- })
- if (!value) {
- throw new Error(
- 'Please ensure manually that your local repository is clean and up to date.',
- )
- }
- }
- if (stderr.indexOf('bad object') !== -1) {
- // eslint-disable-next-line no-shadow
- const { status, stdout, stderr } = spawnSync(
- 'git',
- [
- 'fetch',
- `https://github.com/${REPO_OWNER}/${REPO_NAME}.git`,
- TARGET_BRANCH,
- ],
- spawnOptions,
- )
- if (status) {
- console.log(stdout.toString())
- console.error(stderr.toString())
- throw new Error('Failed to fetch, please ensure manually that your local repository is up to date')
- }
- }
- if (!rewindGitHistory(spawnOptions, REMOTE_HEAD)) {
- throw new Error(
- 'Failed to reset, please ensure manually that your local repository is clean and up to date.',
- )
- }
- }
- return [await latestRelease, LOCAL_HEAD]
- }
|