123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- 'use strict';
- const fs = require('fs');
- const os = require('os');
- const path = require('path');
- const glob = require('glob');
- const spawnSync = require('../lib/spawn-sync');
- const publishRelease = require('publish-release');
- const releaseNotes = require('./lib/release-notes');
- const uploadToAzure = require('./lib/upload-to-azure-blob');
- const uploadLinuxPackages = require('./lib/upload-linux-packages');
- const CONFIG = require('../config');
- const { REPO_OWNER, MAIN_REPO, NIGHTLY_RELEASE_REPO } = CONFIG;
- const yargs = require('yargs');
- const argv = yargs
- .usage('Usage: $0 [options]')
- .help('help')
- .describe(
- 'assets-path',
- 'Path to the folder where all release assets are stored'
- )
- .describe(
- 'azure-blob-path',
- 'Indicates the Azure Blob Path path in which the assets should be uploaded'
- )
- .describe(
- 'create-github-release',
- 'Creates a GitHub release for this build, draft if release branch or public if Nightly'
- )
- .describe(
- 'linux-repo-name',
- 'If specified, uploads Linux packages to the given repo name on packagecloud'
- )
- .wrap(yargs.terminalWidth()).argv;
- const releaseVersion = CONFIG.computedAppVersion;
- const isNightlyRelease = CONFIG.channel === 'nightly';
- const assetsPath = argv.assetsPath || CONFIG.buildOutputPath;
- const assetsPattern =
- '/**/*(*.exe|*.zip|*.nupkg|*.tar.gz|*.rpm|*.deb|RELEASES*|atom-api.json)';
- const assets = glob.sync(assetsPattern, { root: assetsPath, nodir: true });
- const azureBlobPath = argv.azureBlobPath || `releases/v${releaseVersion}/`;
- if (!assets || assets.length === 0) {
- console.error(`No assets found under specified path: ${assetsPath}`);
- process.exit(1);
- }
- async function uploadArtifacts() {
- let releaseForVersion = await releaseNotes.getRelease(
- releaseVersion,
- process.env.GITHUB_TOKEN
- );
- if (releaseForVersion.exists && !releaseForVersion.isDraft) {
- console.log(
- `Published release already exists for ${releaseVersion}, skipping upload.`
- );
- return;
- }
- if (
- process.env.ATOM_RELEASES_S3_KEY &&
- process.env.ATOM_RELEASES_S3_SECRET &&
- process.env.ATOM_RELEASES_S3_BUCKET
- ) {
- console.log(
- `Uploading ${
- assets.length
- } release assets for ${releaseVersion} to Azure Blob Storage under '${azureBlobPath}'`
- );
- await uploadToAzure(
- process.env.ATOM_RELEASES_AZURE_CONN_STRING,
- azureBlobPath,
- assets
- );
- } else {
- console.log(
- '\nEnvironment variables "ATOM_RELEASES_S3_BUCKET", "ATOM_RELEASES_S3_KEY" and/or "ATOM_RELEASES_S3_SECRET" are not set, skipping S3 upload.'
- );
- }
- if (argv.linuxRepoName) {
- if (process.env.PACKAGE_CLOUD_API_KEY) {
- await uploadLinuxPackages(
- argv.linuxRepoName,
- process.env.PACKAGE_CLOUD_API_KEY,
- releaseVersion,
- assets
- );
- } else {
- console.log(
- '\nEnvironment variable "PACKAGE_CLOUD_API_KEY" is not set, skipping PackageCloud upload.'
- );
- }
- } else {
- console.log(
- '\nNo Linux package repo name specified, skipping Linux package upload.'
- );
- }
- const oldReleaseNotes = releaseForVersion.releaseNotes;
- if (oldReleaseNotes) {
- const oldReleaseNotesPath = path.resolve(
- os.tmpdir(),
- 'OLD_RELEASE_NOTES.md'
- );
- console.log(
- `Saving existing ${releaseVersion} release notes to ${oldReleaseNotesPath}`
- );
- fs.writeFileSync(oldReleaseNotesPath, oldReleaseNotes, 'utf8');
- // This line instructs VSTS to upload the file as an artifact
- console.log(
- `##vso[artifact.upload containerfolder=OldReleaseNotes;artifactname=OldReleaseNotes;]${oldReleaseNotesPath}`
- );
- }
- if (argv.createGithubRelease) {
- console.log(`\nGenerating new release notes for ${releaseVersion}`);
- let newReleaseNotes = '';
- if (isNightlyRelease) {
- newReleaseNotes = await releaseNotes.generateForNightly(
- releaseVersion,
- process.env.GITHUB_TOKEN,
- oldReleaseNotes
- );
- } else {
- newReleaseNotes = await releaseNotes.generateForVersion(
- releaseVersion,
- process.env.GITHUB_TOKEN,
- oldReleaseNotes
- );
- }
- console.log(`New release notes:\n\n${newReleaseNotes}`);
- const releaseSha = !isNightlyRelease
- ? spawnSync('git', ['rev-parse', 'HEAD'])
- .stdout.toString()
- .trimEnd()
- : 'master'; // Nightly tags are created in REPO_OWNER/NIGHTLY_RELEASE_REPO so the SHA is irrelevant
- console.log(`Creating GitHub release v${releaseVersion}`);
- const release = await publishReleaseAsync({
- token: process.env.GITHUB_TOKEN,
- owner: REPO_OWNER,
- repo: !isNightlyRelease ? MAIN_REPO : NIGHTLY_RELEASE_REPO,
- name: CONFIG.computedAppVersion,
- notes: newReleaseNotes,
- target_commitish: releaseSha,
- tag: `v${CONFIG.computedAppVersion}`,
- draft: !isNightlyRelease,
- prerelease: CONFIG.channel !== 'stable',
- editRelease: true,
- reuseRelease: true,
- skipIfPublished: true,
- assets
- });
- console.log('Release published successfully: ', release.html_url);
- } else {
- console.log('Skipping GitHub release creation');
- }
- }
- async function publishReleaseAsync(options) {
- return new Promise((resolve, reject) => {
- publishRelease(options, (err, release) => {
- if (err) {
- reject(err);
- } else {
- resolve(release);
- }
- });
- });
- }
- // Wrap the call the async function and catch errors from its promise because
- // Node.js doesn't yet allow use of await at the script scope
- uploadArtifacts().catch(err => {
- console.error('An error occurred while uploading the release:\n\n', err);
- process.exit(1);
- });
|