Skip to content

Commit 9d90c8c

Browse files
committed
feat: add support for output manifest
1 parent 61dd574 commit 9d90c8c

File tree

8 files changed

+94
-16
lines changed

8 files changed

+94
-16
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ dist/
55
docs/
66
key.json
77
node_modules/
8+
upload.json

src/commands/upload.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// eslint-disable-next-line node/no-extraneous-import
2+
import * as _colors from 'colors';
13
import * as fs from 'fs';
24
import * as fsPath from 'path';
35
import * as manifest from '../manifest';
@@ -11,6 +13,7 @@ interface UploadOptions {
1113
bucket: string;
1214
force?: boolean;
1315
googleCloudProject?: string;
16+
outputFile?: string;
1417
ref?: string;
1518
site: string;
1619
ttl?: string;
@@ -75,7 +78,8 @@ export class UploadCommand {
7578
(site as string) || 'default',
7679
this.options.ref || gitData.ref,
7780
this.options.branch || gitData.branch || '',
78-
gitData.commit
81+
gitData.commit,
82+
googleCloudProject
7983
);
8084
await manifestObj.createFromDirectory(path);
8185
if (config.redirectTrailingSlashes === false) {
@@ -105,5 +109,27 @@ export class UploadCommand {
105109
this.options.force,
106110
ttl
107111
);
112+
113+
if (this.options.outputFile) {
114+
const data = JSON.stringify(manifestObj.toOutputJSON(), null, 2);
115+
const outputDir = fsPath.dirname(this.options.outputFile);
116+
if (!fs.existsSync(outputDir)) {
117+
fs.mkdirSync(outputDir, {recursive: true});
118+
}
119+
fs.writeFileSync(this.options.outputFile, data);
120+
}
121+
122+
console.log(
123+
`Finalized upload for site: ${manifestObj.site} -> ${manifestObj.branch} @ ${manifestObj.shortSha}`
124+
);
125+
const cleanDate = new Date(manifestObj.commit.author.timestamp * 1000);
126+
console.log(
127+
`[${cleanDate.getFullYear()}-${cleanDate.getMonth()}-${cleanDate.getDate()}] <${
128+
manifestObj.commit.author.email
129+
}> ${manifestObj.commit.message.split('Change-Id')[0].trim()}`
130+
);
131+
console.log('Dashboard:'.blue + ` ${manifestObj.urls.ui}`);
132+
console.log(' Build:'.blue + ` ${manifestObj.urls.stagingSha}`);
133+
console.log(' Staging:'.green + ` ${manifestObj.urls.stagingBranch}`);
108134
}
109135
}

src/gitdata.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export async function getGitData(path: string): Promise<GitData> {
3939
commit: {
4040
message: cleanMessage,
4141
author: {
42+
timestamp: commit.committer.timestamp,
4243
name: commit.author.name,
4344
email: commit.author.email,
4445
},

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ async function main() {
1616
.option('-b, --branch <branch>', 'branch', '')
1717
.option('-f, --force', 'force', false)
1818
.option('-t, --ttl <ttl>', 'ttl', undefined)
19+
.option('-o, --output-file <path>', 'output file', '')
1920
.action(async (path, options) => {
2021
const cmd = new UploadCommand(options);
2122
await cmd.run(path);

src/manifest.ts

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import * as fs from 'fs';
33
import * as fsPath from 'path';
44
import * as mimeTypes from 'mime-types';
55

6+
import {branchToHostnameToken} from './server';
7+
68
const walk = function (path: string, newFiles?: string[]) {
79
let files = newFiles || [];
810
fs.readdirSync(path).forEach(file => {
@@ -34,13 +36,20 @@ export interface Redirect {
3436
interface GitAuthor {
3537
email: string;
3638
name: string;
39+
timestamp: number;
3740
}
3841

3942
export interface Commit {
4043
message: string;
4144
author: GitAuthor;
4245
}
4346

47+
export interface ManifestUrls {
48+
stagingBranch: string;
49+
stagingSha: string;
50+
ui: string;
51+
}
52+
4453
export interface SerializedManifest {
4554
site: string;
4655
ref: string;
@@ -66,8 +75,15 @@ export class Manifest {
6675
localizationPathFormat: string;
6776
headers: Record<string, Record<string, string>>;
6877
commit: Commit;
69-
70-
constructor(site: string, ref: string, branch: string, commit: Commit) {
78+
googleCloudProject: string;
79+
80+
constructor(
81+
site: string,
82+
ref: string,
83+
branch: string,
84+
commit: Commit,
85+
googleCloudProject: string
86+
) {
7187
this.files = [];
7288
this.redirects = [];
7389
this.site = site;
@@ -78,6 +94,7 @@ export class Manifest {
7894
this.localizationPathFormat = DEFAULT_LOCALIZATION_PATH_FORMAT;
7995
this.headers = {};
8096
this.commit = commit;
97+
this.googleCloudProject = googleCloudProject;
8198
}
8299

83100
async createFromDirectory(path: string) {
@@ -136,4 +153,32 @@ export class Manifest {
136153
});
137154
return pathsToHashes;
138155
}
156+
157+
toOutputJSON() {
158+
return {
159+
urls: this.urls,
160+
files: this.files,
161+
commit: this.commit,
162+
};
163+
}
164+
165+
get urls(): ManifestUrls {
166+
// TODO: Allow customizing the staging URL using `fileset.yaml` configuration.
167+
const hostnameSuffix = `fileset-dot-${this.googleCloudProject}.appspot.com`;
168+
const stagingShaUrl =
169+
this.site === 'default'
170+
? `https://${this.shortSha}-dot-${hostnameSuffix}`
171+
: `https://${this.site}-${this.shortSha}-dot-${hostnameSuffix}`;
172+
const branchToken = branchToHostnameToken(this.branch);
173+
const stagingBranchUrl =
174+
this.site === 'default'
175+
? `https://${branchToken}-dot-${hostnameSuffix}`
176+
: `https://${this.site}-${branchToken}-dot-${hostnameSuffix}`;
177+
const uiUrl = `https://${hostnameSuffix}/fileset/sites/${this.site}/${this.shortSha}`;
178+
return {
179+
stagingBranch: stagingBranchUrl,
180+
stagingSha: stagingShaUrl,
181+
ui: uiUrl,
182+
};
183+
}
139184
}

src/server.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ import * as server from './server';
33
import {ExecutionContext} from 'ava';
44
import test from 'ava';
55

6+
test('Test branchToHostnameToken', (t: ExecutionContext) => {
7+
t.deepEqual(server.branchToHostnameToken('main'), 'main');
8+
t.deepEqual(server.branchToHostnameToken('feature/foo'), 'foo');
9+
t.deepEqual(server.branchToHostnameToken('workspace/foo'), 'foo');
10+
t.deepEqual(server.branchToHostnameToken('b/foo'), 'foo');
11+
t.deepEqual(server.branchToHostnameToken('foo/bar'), 'foo--bar');
12+
});
13+
614
test('Test parseHostname', (t: ExecutionContext) => {
715
t.deepEqual(
816
server.parseHostname({

src/server.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,15 @@ export const listManifests = async (siteId: string, manifestType?: string) => {
9090
return null;
9191
};
9292

93+
export function branchToHostnameToken(branch: string) {
94+
let hostname = branch;
95+
for (const prefix of defaults.COMMON_BRANCH_PREFIXES) {
96+
hostname = hostname.replace(prefix, '');
97+
}
98+
hostname = hostname.replace(/\//g, '--');
99+
return hostname;
100+
}
101+
93102
export function parseHostname(
94103
options: ParseHostnameOptions
95104
): ManifestLookupOptions[] {

src/upload.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -217,17 +217,4 @@ async function finalize(
217217
// const routerKey = datastore.key(['Fileset2Router', manifest.site]);
218218
// const router = await datastore.get(routerKey);
219219
// const entity = router && router[0];
220-
console.log(
221-
`Finalized upload for site: ${manifest.site} -> ${manifest.branch} @ ${manifest.shortSha}`
222-
);
223-
// TODO: Allow customizing the staging URL using `fileset.yaml` configuration.
224-
if (manifest.site === 'default') {
225-
console.log(
226-
`Staged: https://${manifest.shortSha}-dot-fileset-dot-${googleCloudProject}.appspot.com`
227-
);
228-
} else {
229-
console.log(
230-
`Staged: https://${manifest.site}-${manifest.shortSha}-dot-fileset-dot-${googleCloudProject}.appspot.com`
231-
);
232-
}
233220
}

0 commit comments

Comments
 (0)