Skip to content

Commit 63fcd27

Browse files
committed
ci: add snapshots scripts
1 parent e5f0b7b commit 63fcd27

File tree

5 files changed

+121
-6
lines changed

5 files changed

+121
-6
lines changed

.monorepo.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@
6565
}
6666
],
6767
"version": "0.0.29",
68-
"hash": "c5b7ac4219d4e5bd7beb2230043fb876"
68+
"hash": "c5b7ac4219d4e5bd7beb2230043fb876",
69+
"snapshotRepo": "angular/angular-devkit-core-builds"
6970
},
7071
"@angular-devkit/schematics": {
7172
"name": "Schematics",
@@ -76,7 +77,8 @@
7677
}
7778
],
7879
"version": "0.0.52",
79-
"hash": "5da7eec7e29add6e2d9f6018df033025"
80+
"hash": "5da7eec7e29add6e2d9f6018df033025",
81+
"snapshotRepo": "angular/angular-devkit-schematics-builds"
8082
},
8183
"@angular-devkit/schematics-cli": {
8284
"name": "Schematics CLI",

lib/packages.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
'use strict';
99

1010
import { JsonObject } from '@angular-devkit/core';
11+
import { execSync } from 'child_process';
1112
import * as crypto from 'crypto';
1213
import * as fs from 'fs';
1314
import * as path from 'path';
@@ -31,6 +32,10 @@ export interface PackageInfo {
3132
packageJson: JsonObject;
3233
dependencies: string[];
3334

35+
snapshot: boolean;
36+
snapshotRepo: string;
37+
snapshotHash: string;
38+
3439
dirty: boolean;
3540
hash: string;
3641
version: string;
@@ -156,6 +161,16 @@ const packageJsonPaths = _findAllPackageJson(path.join(__dirname, '..'), exclude
156161
.filter(p => p != path.join(__dirname, '../package.json'));
157162

158163

164+
let gitShaCache: string;
165+
function _getSnapshotHash(_pkg: PackageInfo): string {
166+
if (!gitShaCache) {
167+
gitShaCache = execSync('git log --format=%h -n1').toString().trim();
168+
}
169+
170+
return gitShaCache;
171+
}
172+
173+
159174
// All the supported packages. Go through the packages directory and create a map of
160175
// name => PackageInfo. This map is partial as it lacks some information that requires the
161176
// map itself to finish building.
@@ -191,6 +206,12 @@ export const packages: PackageMap =
191206
name,
192207
packageJson,
193208

209+
snapshot: !!monorepoPackages[name].snapshotRepo,
210+
snapshotRepo: monorepoPackages[name].snapshotRepo,
211+
get snapshotHash() {
212+
return _getSnapshotHash(this);
213+
},
214+
194215
dependencies: [],
195216
hash: '',
196217
dirty: false,

scripts/build.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ function _build(logger: logging.Logger) {
158158
}
159159

160160

161-
export default function(argv: { local?: boolean }, logger: logging.Logger) {
161+
export default function(argv: { local?: boolean, snapshot?: boolean }, logger: logging.Logger) {
162162
_clean(logger);
163163

164164
const sortedPackages = _sortPackages();
@@ -295,8 +295,19 @@ export default function(argv: { local?: boolean }, logger: logging.Logger) {
295295
if (obj && obj[depName]) {
296296
if (argv.local) {
297297
obj[depName] = packages[depName].tar;
298-
} else if (obj[depName] == '0.0.0') {
299-
obj[depName] = v;
298+
} else if (argv.snapshot) {
299+
const pkg = packages[depName];
300+
if (!pkg.snapshotRepo) {
301+
versionLogger.error(
302+
`Package ${JSON.stringify(depName)} is not published as a snapshot. `
303+
+ `Fixing to current version ${v}.`,
304+
);
305+
obj[depName] = v;
306+
} else {
307+
obj[depName] = `github:${pkg.snapshotRepo}#${pkg.snapshotHash}`;
308+
}
309+
} else if ((obj[depName] as string).match(/\b0\.0\.0\b/)) {
310+
obj[depName] = (obj[depName] as string).replace(/\b0\.0\.0\b/, v);
300311
}
301312
}
302313
}

scripts/publish.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { logging } from '@angular-devkit/core';
99
import { resolve } from '@angular-devkit/core/node';
1010
import * as stream from 'stream';
1111
import { packages } from '../lib/packages';
12+
import build from './build';
1213

1314
const npm = require(resolve('npm', { basedir: '/', checkGlobal: true }));
1415

@@ -19,7 +20,6 @@ class NullStream extends stream.Writable {
1920

2021
export default function (_: {}, logger: logging.Logger) {
2122
logger.info('Building...');
22-
const build = require('./build').default;
2323
build({}, logger.createChild('build'));
2424

2525
return new Promise<void>((resolve, reject) => {

scripts/snapshots.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
import { logging } from '@angular-devkit/core';
9+
import { execSync } from 'child_process';
10+
import * as fs from 'fs';
11+
import * as os from 'os';
12+
import * as path from 'path';
13+
import { packages } from '../lib/packages';
14+
import build from './build';
15+
16+
17+
function _copy(from: string, to: string) {
18+
fs.readdirSync(from)
19+
.forEach(name => {
20+
const fromPath = path.join(from, name);
21+
const toPath = path.join(to, name);
22+
if (fs.statSync(fromPath).isDirectory()) {
23+
if (!fs.existsSync(toPath)) {
24+
fs.mkdirSync(toPath);
25+
}
26+
_copy(fromPath, toPath);
27+
} else {
28+
fs.writeFileSync(toPath, fs.readFileSync(fromPath));
29+
}
30+
});
31+
}
32+
33+
34+
export default function(opts: { force?: boolean }, logger: logging.Logger) {
35+
// Get the SHA.
36+
if (execSync(`git status --porcelain`).toString() && !opts.force) {
37+
logger.error('You cannot run snapshots with local changes.');
38+
process.exit(1);
39+
}
40+
41+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'angular-devkit-publish-'));
42+
const message = execSync(`git log --format="%h %s" -n1`).toString().trim();
43+
44+
// Run build.
45+
logger.info('Building...');
46+
build({ snapshot: true }, logger.createChild('build'));
47+
48+
for (const packageName of Object.keys(packages)) {
49+
const pkg = packages[packageName];
50+
51+
if (!pkg.snapshot) {
52+
logger.warn(`Skipping ${pkg.name}.`);
53+
continue;
54+
}
55+
56+
logger.info(`Publishing ${pkg.name} to repo ${JSON.stringify(pkg.snapshotRepo)}.`);
57+
58+
const publishLogger = logger.createChild('publish');
59+
publishLogger.debug('Temporary directory: ' + root);
60+
61+
const url = `https://github.com/${pkg.snapshotRepo}.git`;
62+
execSync(`git clone ${JSON.stringify(url)}`, { cwd: root });
63+
64+
const destPath = path.join(root, path.basename(pkg.snapshotRepo));
65+
_copy(pkg.dist, destPath);
66+
67+
execSync(`git config credential.helper "store --file=.git/credentials"`, { cwd: destPath });
68+
fs.writeFileSync(path.join(destPath, '.git/credentials'),
69+
`https://${process.env['GITHUB_ACCESS_TOKEN']}@github.com`);
70+
71+
// Make sure that every snapshots is unique.
72+
fs.writeFileSync(path.join(destPath, 'uniqueId'), '' + new Date());
73+
74+
// Commit and push.
75+
execSync(`git add -A`, { cwd: destPath });
76+
execSync(`git commit -am ${JSON.stringify(message)}`, { cwd: destPath });
77+
execSync(`git tag ${pkg.snapshotHash}`, { cwd: destPath });
78+
execSync(`git push origin`, { cwd: destPath });
79+
execSync(`git push --tags origin`, { cwd: destPath });
80+
}
81+
}

0 commit comments

Comments
 (0)