diff --git a/.npmignore b/.npmignore index 039e6414..38b1ae8a 100644 --- a/.npmignore +++ b/.npmignore @@ -31,3 +31,12 @@ tsconfig.json # config files *.yml + +# assorted unimportant tooling files +.vscode/ +.prettierrc +CODE_OF_CONDUCT.md +CONTRIBUTING.md + +# for tooling purposes only +/script/update-embedded-git.js diff --git a/docs/releases.md b/docs/releases.md index 85cd06e2..e7f0764b 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -1,9 +1,25 @@ # Releases +## Update Git + +The most important part of the release process is updating the embedded Git package. This can be done using this one-liner: + +```sh +npm run update-embedded-git +``` + +This script: + +- retrieves the latest `dugite-native` release from the GitHub API +- gets the checksums embedded in the release +- generates the `script/embedded-git.json` payload to be used at install time + +## Publishing to NPM + Releases are done to NPM, and are currently limited to the core team. ```sh -# to ensure everything is up-to-date +# to ensure everything is up-to-date and tests pass npm i # you might need to do a different sort of version bump here npm version minor diff --git a/package.json b/package.json index 31d43529..7fa83b6b 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,8 @@ "test:external": "mocha -t 30000 --require ts-node/register test/external/*.ts", "postinstall": "node ./script/download-git.js", "prettify": "prettier \"{examples,lib,script,test}/**/*.ts\" --write", - "is-it-pretty": "prettier \"{examples,lib,script,test}/**/*.ts\" --list-different" + "is-it-pretty": "prettier \"{examples,lib,script,test}/**/*.ts\" --list-different", + "update-embedded-git": "node ./script/update-embedded-git.js" }, "engines": { "node": ">= 6", diff --git a/script/config.js b/script/config.js index 9f32eb40..45f56592 100644 --- a/script/config.js +++ b/script/config.js @@ -3,6 +3,8 @@ const path = require('path') const os = require('os') const fs = require('fs') +const embeddedGit = require('./embedded-git.json') + function getConfig() { const config = { outputPath: path.join(__dirname, '..', 'git'), @@ -12,30 +14,15 @@ function getConfig() { tempFile: '' } - if (process.platform === 'darwin') { - config.checksum = 'e95eefd33c8305aa4b362fe76d4a499cd7c1f11ff3183fc10009317466bc309f' - config.source = - 'https://github.com/desktop/dugite-native/releases/download/v2.18.0-4/dugite-native-v2.18.0-macOS.tar.gz' - } else if (process.platform === 'win32') { - if (os.arch() === 'x64') { - config.checksum = '186cba377cbb7f2bb0d0061ccdd9ddc12c7acc8381a2f56e3c59952a1ecc09a9' - config.source = - 'https://github.com/desktop/dugite-native/releases/download/v2.18.0-4/dugite-native-v2.18.0-windows-x64.tar.gz' - } else { - config.checksum = '680769787069722f283bf0e5f0acaed37c049bbe81a27ebda6fa4b9b8ffe86d1' - config.source = - 'https://github.com/desktop/dugite-native/releases/download/v2.18.0-4/dugite-native-v2.18.0-windows-x86.tar.gz' - } - } else if (process.platform === 'linux') { - if (os.arch() === 'arm64') { - config.checksum = '5182bc8660ec3052d9ae05ee209f95a567eed30d7c6c60920c25ca68ce6f032b' - config.source = - 'https://github.com/desktop/dugite-native/releases/download/v2.18.0-4/dugite-native-v2.18.0-arm64.tar.gz' - } else { - config.checksum = '8eb1468bd10927229c7adbc41e0dec2b0f1fdbd0605fda9194cca028b35d52b1' - config.source = - 'https://github.com/desktop/dugite-native/releases/download/v2.18.0-4/dugite-native-v2.18.0-ubuntu.tar.gz' - } + const key = `${process.platform}-${os.arch()}` + + const entry = embeddedGit[key] + + if (entry != null) { + config.checksum = entry.checksum + config.source = entry.url + } else { + console.log(`No embedded Git found for ${process.platform} and architecture ${os.arch()}`) } if (config.source !== '') { diff --git a/script/embedded-git.json b/script/embedded-git.json new file mode 100644 index 00000000..5339c455 --- /dev/null +++ b/script/embedded-git.json @@ -0,0 +1,27 @@ +{ + "win32-x64": { + "name": "dugite-native-v2.19.0-windows-x64.tar.gz", + "url": "https://github.com/desktop/dugite-native/releases/download/v2.19.0-1/dugite-native-v2.19.0-windows-x64.tar.gz", + "checksum": "d38baa1e5c559e2d0172a84f6e5ce996946f60ddd4432632c4ead90e49b73d60" + }, + "win32-ia32": { + "name": "dugite-native-v2.19.0-windows-x86.tar.gz", + "url": "https://github.com/desktop/dugite-native/releases/download/v2.19.0-1/dugite-native-v2.19.0-windows-x86.tar.gz", + "checksum": "44dc57777959309ed4115e24ce0598dae19c93ce9731ef3a612f549b53e7ae9e" + }, + "darwin-x64": { + "name": "dugite-native-v2.19.0-macOS.tar.gz", + "url": "https://github.com/desktop/dugite-native/releases/download/v2.19.0-1/dugite-native-v2.19.0-macOS.tar.gz", + "checksum": "53dcc276a404c8769104fa3ddf5595a86a7e22016449fb79d9bc5724a5563d80" + }, + "linux-x64": { + "name": "dugite-native-v2.19.0-ubuntu.tar.gz", + "url": "https://github.com/desktop/dugite-native/releases/download/v2.19.0-1/dugite-native-v2.19.0-ubuntu.tar.gz", + "checksum": "04b4f70544e798467f07905b0b05853d6a34f4cfcbf63481e94907c6b9aa5876" + }, + "linux-arm64": { + "name": "dugite-native-v2.19.0-arm64.tar.gz", + "url": "https://github.com/desktop/dugite-native/releases/download/v2.19.0-1/dugite-native-v2.19.0-arm64.tar.gz", + "checksum": "0589faac66321c27175f6fc9b19de13e6c1c091ea9de1f206d184d42ee020b47" + } +} \ No newline at end of file diff --git a/script/update-embedded-git.js b/script/update-embedded-git.js new file mode 100644 index 00000000..4abc29da --- /dev/null +++ b/script/update-embedded-git.js @@ -0,0 +1,113 @@ +const request = require('request') +const fs = require('fs') +const path = require('path') + +const options = { + url: `https://api.github.com/repos/desktop/dugite-native/releases/latest`, + headers: { + Accept: 'application/json', + 'User-Agent': 'dugite' + }, + secureProtocol: 'TLSv1_2_method', + json: true +} + +request(options, async (err, response, release) => { + if (err) { + console.error('Unable to get latest release', err) + return + } + + const { tag_name, assets } = release + + console.log(`Updating embedded git config to use version ${tag_name}`) + + const output = { + 'win32-x64': await findWindows64BitRelease(assets), + 'win32-ia32': await findWindows32BitRelease(assets), + 'darwin-x64': await findMacOS64BitRelease(assets), + 'linux-x64': await findLinux64BitRelease(assets), + 'linux-arm64': await findLinuxARM64Release(assets) + } + + const fileContents = JSON.stringify(output, null, 2) + + const embeddedGitPath = path.join(__dirname, 'embedded-git.json') + + fs.writeFileSync(embeddedGitPath, fileContents, 'utf8') + + console.log( + `Done! Don't forget to commit any changes and run the test suite again with \`npm i\` to confirm they pass!` + ) +}) + +function findWindows64BitRelease(assets) { + const asset = assets.find(a => a.name.endsWith('-windows-x64.tar.gz')) + if (asset == null) { + throw new Error('Could not find Windows 64-bit archive in latest release') + } + return getDetailsForAsset(assets, asset) +} + +function findWindows32BitRelease(assets) { + const asset = assets.find(a => a.name.endsWith('-windows-x86.tar.gz')) + if (asset == null) { + throw new Error('Could not find Windows 32-bit archive in latest release') + } + return getDetailsForAsset(assets, asset) +} + +function findMacOS64BitRelease(assets) { + const asset = assets.find(a => a.name.endsWith('-macOS.tar.gz')) + if (asset == null) { + throw new Error('Could not find MacOS 64-bit archive in latest release') + } + return getDetailsForAsset(assets, asset) +} + +function findLinux64BitRelease(assets) { + const asset = assets.find(a => a.name.endsWith('-ubuntu.tar.gz')) + if (asset == null) { + throw new Error('Could not find Linux 64-bit archive in latest release') + } + return getDetailsForAsset(assets, asset) +} + +function findLinuxARM64Release(assets) { + const asset = assets.find(a => a.name.endsWith('-arm64.tar.gz')) + if (asset == null) { + throw new Error('Could not find Linux ARM64 archive in latest release') + } + return getDetailsForAsset(assets, asset) +} + +function downloadChecksum(url) { + return new Promise((resolve, reject) => { + const options = { + url, + headers: { + Accept: 'application/octet-stream', + 'User-Agent': 'dugite-native' + }, + secureProtocol: 'TLSv1_2_method' + } + + request(options, (err, response, body) => { + if (err) { + reject(err) + return + } + + resolve(body) + }) + }) +} + +async function getDetailsForAsset(assets, currentAsset) { + const { name } = currentAsset + const url = currentAsset.browser_download_url + const checksumFile = assets.find(a => a.name === `${name}.sha256`) + const checksumRaw = await downloadChecksum(checksumFile.browser_download_url) + const checksum = checksumRaw.trim() + return { name, url, checksum } +} diff --git a/test/helpers.ts b/test/helpers.ts index 235932fa..ea4e7cb1 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -1,8 +1,8 @@ import { GitProcess, IGitResult } from '../lib' // NOTE: bump these versions to the latest stable releases -export const gitVersion = '2.18.0' -export const gitLfsVersion = '2.5.0' +export const gitVersion = '2.19.0' +export const gitLfsVersion = '2.5.2' const temp = require('temp').track()