Skip to content

Commit 7a5e481

Browse files
committed
Merge pull request #15 from AlexKVal/docs-repo
Add documents publishing
2 parents 9e43c38 + e0d568d commit 7a5e481

File tree

2 files changed

+157
-87
lines changed

2 files changed

+157
-87
lines changed

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,44 @@ including `bower` publishing, for you - automatically.
3535
_Initial idea is got from `React-Bootstrap` release tools `./tools/release`,
3636
that have been written by [Matt Smith @mtscout6](https://github.com/mtscout6)_
3737

38+
#### Publishing of built documents static pages
39+
40+
If your project compiles static documentation pages (as e.g. `React-Boostrap` does)
41+
and needs to publish them to standalone repo / hosting (via `git push`),
42+
you can do it the same way the `bower` package releasing done.
43+
44+
Just create additional github repo for your static documents site.
45+
46+
E.g. [react-bootstrap.github.io.git](https://github.com/react-bootstrap/react-bootstrap.github.io)
47+
48+
Add it as `'release-script'.docsRepo` into your `package.json`:
49+
```js
50+
"release-script": {
51+
"docsRepo": "[email protected]:<author>/original-project-name-github.io.git"
52+
}
53+
```
54+
Default folders for documents are:
55+
- `"docsRoot": "docs-built"` folder where the documents files will be built (by your custom building scripts)
56+
- `"tmpDocsRepo": "tmp-docs-repo"` temporary folder.
57+
58+
It is advised to add them both into `.gitignore`.
59+
60+
You can customize them as you need:
61+
```js
62+
"release-script": {
63+
"docsRepo": "[email protected]:<author>/original-project-name-github.io.git"
64+
"docsRoot": "docs-built",
65+
"tmpDocsRepo": "tmp-docs-repo"
66+
}
67+
```
68+
69+
If you need to publish only documents (say with some minor fixes),
70+
this is as simple as:
71+
```
72+
> release --only-docs
73+
```
74+
In this case the `package.json` version will be bumped with `--preid docs` as `0.10.0` => `0.10.0-docs.0`
75+
3876
#### Pre-release versions publishing
3977

4078
Say you need to publish pre-release `v0.25.100-pre.0` version
@@ -136,6 +174,10 @@ You can set a custom message for release via `--notes` CLI option:
136174
- then by `git add -A .` adds all bower distr files to the temporary git repo
137175
- commits, tags and pushes the same as for the `npm` package.
138176
- then deletes the `tmpBowerRepo` folder
177+
- id `docsRepo` field is present in the `package.json`, then it pushes builded documents to their repo.
178+
It is done the same way as `bower` repo.
179+
180+
If command line `--only-docs` option is set, then `github`, `npm` and `bower` publishing steps will be skipped.
139181

140182
## Installation
141183

src/release.js

Lines changed: 115 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,18 @@ const bowerRoot = path.join(repoRoot, (configOptions.bowerRoot || 'amd/'));
3939
const tmpBowerRepo = path.join(repoRoot, (configOptions.tmpBowerRepo || 'tmp-bower-repo'));
4040
const bowerRepo = configOptions.bowerRepo; // if it is not set, then there is no bower repo
4141

42+
const docsRoot = path.join(repoRoot, (configOptions.docsRoot || 'docs-built/'));
43+
const tmpDocsRepo = path.join(repoRoot, (configOptions.tmpDocsRepo || 'tmp-docs-repo'));
44+
const docsRepo = configOptions.docsRepo; // if it is not set, then there is no docs/site repo
45+
4246
const githubToken = process.env.GITHUB_TOKEN;
4347

4448
const altPkgRootFolder = configOptions.altPkgRootFolder;
4549

4650
//------------------------------------------------------------------------------
4751
// command line options
4852
const yargsConf = yargs
49-
.usage('Usage: $0 <version> [--preid <identifier>]')
53+
.usage('Usage: $0 <version> [--preid <identifier>]\nor\nUsage: $0 --only-docs')
5054
.example('$0 minor --preid beta', 'Release with minor version bump with pre-release tag. (npm tag `beta`)')
5155
.example('$0 major', 'Release with major version bump')
5256
.example('$0 major --notes "This is new cool version"', 'Add a custom message to release')
@@ -67,6 +71,12 @@ const yargsConf = yargs
6771
describe: 'Npm tag name for the pre-release version.\nIf it is not provided, then `preid` value is used',
6872
type: 'string'
6973
})
74+
.option('only-docs', {
75+
alias: 'docs',
76+
demand: false,
77+
default: false,
78+
describe: 'Publish only documents'
79+
})
7080
.option('dry-run', {
7181
alias: 'n',
7282
demand: false,
@@ -87,12 +97,13 @@ const yargsConf = yargs
8797
const argv = yargsConf.argv;
8898

8999
if (argv.dryRun) console.log('DRY RUN'.magenta);
100+
if (argv.onlyDocs) console.log('Publish only documents'.magenta);
90101

91102
config.silent = !argv.verbose;
92103

93104
const versionBumpOptions = {
94105
type: argv._[0],
95-
preid: argv.preid,
106+
preid: argv.onlyDocs ? 'docs' : argv.preid,
96107
npmTagName: argv.tag || argv.preid
97108
};
98109

@@ -140,6 +151,28 @@ function getOwnerAndRepo(url) {
140151
return (gitUrlBase || url).split('/');
141152
}
142153

154+
function releaseAdRepo(repo, srcFolder, tmpFolder, vVersion) {
155+
if (!repo || !srcFolder || !tmpFolder || !vVersion) {
156+
printErrorAndExit('Bug error. Create github issue: releaseAdRepo - One of parameters is not set.');
157+
}
158+
159+
rm('-rf', tmpFolder);
160+
run(`git clone ${repo} ${tmpFolder}`);
161+
pushd(tmpFolder);
162+
rm('-rf', ls(tmpFolder).filter(file => file !== '.git')); // delete all but `.git` dir
163+
cp('-R', srcFolder, tmpFolder);
164+
safeRun('git add -A .');
165+
safeRun(`git commit -m "Release ${vVersion}"`);
166+
safeRun(`git tag -a --message=${vVersion} ${vVersion}`);
167+
safeRun('git push --follow-tags');
168+
popd();
169+
if (argv.dryRun) {
170+
console.log(`[rm -rf ${tmpFolder}]`.grey, 'DRY RUN'.magenta);
171+
} else {
172+
rm('-rf', tmpFolder);
173+
}
174+
}
175+
143176
function release({ type, preid, npmTagName }) {
144177
if (type === undefined && !preid) printErrorAndExit('Must specify version type or preid');
145178

@@ -224,99 +257,94 @@ function release({ type, preid, npmTagName }) {
224257
safeRun('git push --follow-tags');
225258
console.log('Tagged: '.cyan + vVersion.green);
226259

227-
// publish to GitHub
228-
if (githubToken) {
229-
console.log(`GitHub token found ${githubToken}`.green);
230-
console.log('Publishing to GitHub: '.cyan + vVersion.green);
260+
if (!argv.onlyDocs) {
261+
// publish to GitHub
262+
if (githubToken) {
263+
console.log(`GitHub token found ${githubToken}`.green);
264+
console.log('Publishing to GitHub: '.cyan + vVersion.green);
265+
266+
if (argv.dryRun) {
267+
console.log(`[publishing to GitHub]`.grey, 'DRY RUN'.magenta);
268+
} else {
269+
const [githubOwner, githubRepo] = getOwnerAndRepo(npmjson.repository.url || npmjson.repository);
270+
271+
request({
272+
uri: `https://api.github.com/repos/${githubOwner}/${githubRepo}/releases`,
273+
method: 'POST',
274+
json: true,
275+
body: {
276+
tag_name: vVersion, // eslint-disable-line camelcase
277+
name: `${githubRepo} ${vVersion}`,
278+
body: notesForRelease,
279+
draft: false,
280+
prerelease: !!preid
281+
},
282+
headers: {
283+
'Authorization': `token ${githubToken}`,
284+
'User-Agent': 'release-script (https://github.com/alexkval/release-script)'
285+
}
286+
}, function(err, res, body) {
287+
if (err) {
288+
console.log('API request to GitHub, error has occured:'.red);
289+
console.log(err);
290+
console.log('Skip GitHub releasing'.yellow);
291+
} else if (res.statusMessage === 'Unauthorized') {
292+
console.log(`GitHub token ${githubToken} is wrong`.red);
293+
console.log('Skip GitHub releasing'.yellow);
294+
} else {
295+
console.log(`Published at ${body.html_url}`.green);
296+
}
297+
});
298+
}
299+
}
231300

232-
if (argv.dryRun) {
233-
console.log(`[publishing to GitHub]`.grey, 'DRY RUN'.magenta);
301+
// npm
302+
if (isPrivate) {
303+
console.log('Package is private, skipping npm release'.yellow);
234304
} else {
235-
const [githubOwner, githubRepo] = getOwnerAndRepo(npmjson.repository.url || npmjson.repository);
236-
237-
request({
238-
uri: `https://api.github.com/repos/${githubOwner}/${githubRepo}/releases`,
239-
method: 'POST',
240-
json: true,
241-
body: {
242-
tag_name: vVersion, // eslint-disable-line camelcase
243-
name: `${githubRepo} ${vVersion}`,
244-
body: notesForRelease,
245-
draft: false,
246-
prerelease: !!preid
247-
},
248-
headers: {
249-
'Authorization': `token ${githubToken}`,
250-
'User-Agent': 'release-script (https://github.com/alexkval/release-script)'
251-
}
252-
}, function(err, res, body) {
253-
if (err) {
254-
console.log('API request to GitHub, error has occured:'.red);
255-
console.log(err);
256-
console.log('Skip GitHub releasing'.yellow);
257-
} else if (res.statusMessage === 'Unauthorized') {
258-
console.log(`GitHub token ${githubToken} is wrong`.red);
259-
console.log('Skip GitHub releasing'.yellow);
260-
} else {
261-
console.log(`Published at ${body.html_url}`.green);
262-
}
263-
});
305+
console.log('Releasing: '.cyan + 'npm package'.green);
306+
307+
const npmPublishCmd = preid ? `npm publish --tag ${npmTagName}` : 'npm publish';
308+
309+
// publishing just /altPkgRootFolder content
310+
if (altPkgRootFolder) {
311+
// prepare custom `package.json` without `scripts` and `devDependencies`
312+
// because it already has been saved, we safely can use the same object
313+
delete npmjson.files; // because otherwise it would be wrong
314+
delete npmjson.scripts;
315+
delete npmjson.devDependencies;
316+
delete npmjson['release-script']; // this also doesn't belong to output
317+
const regexp = new RegExp(altPkgRootFolder + '\\/?');
318+
npmjson.main = npmjson.main.replace(regexp, ''); // remove folder part from path
319+
`${JSON.stringify(npmjson, null, 2)}\n`.to(path.join(altPkgRootFolder, 'package.json'));
320+
321+
pushd(altPkgRootFolder);
322+
safeRun(npmPublishCmd);
323+
popd();
324+
} else {
325+
safeRun(npmPublishCmd);
326+
}
327+
328+
console.log('Released: '.cyan + 'npm package'.green);
264329
}
265-
}
266330

267-
// npm
268-
if (isPrivate) {
269-
console.log('Package is private, skipping npm release'.yellow);
270-
} else {
271-
console.log('Releasing: '.cyan + 'npm package'.green);
272-
273-
const npmPublishCmd = preid ? `npm publish --tag ${npmTagName}` : 'npm publish';
274-
275-
// publishing just /altPkgRootFolder content
276-
if (altPkgRootFolder) {
277-
// prepare custom `package.json` without `scripts` and `devDependencies`
278-
// because it already has been saved, we safely can use the same object
279-
delete npmjson.files; // because otherwise it would be wrong
280-
delete npmjson.scripts;
281-
delete npmjson.devDependencies;
282-
delete npmjson['release-script']; // this also doesn't belong to output
283-
const regexp = new RegExp(altPkgRootFolder + '\\/?');
284-
npmjson.main = npmjson.main.replace(regexp, ''); // remove folder part from path
285-
`${JSON.stringify(npmjson, null, 2)}\n`.to(path.join(altPkgRootFolder, 'package.json'));
286-
287-
pushd(altPkgRootFolder);
288-
safeRun(npmPublishCmd);
289-
popd();
331+
// bower
332+
if (isPrivate) {
333+
console.log('Package is private, skipping bower release'.yellow);
334+
} else if (bowerRepo) {
335+
console.log('Releasing: '.cyan + 'bower package'.green);
336+
releaseAdRepo(bowerRepo, bowerRoot, tmpBowerRepo, vVersion);
337+
console.log('Released: '.cyan + 'bower package'.green);
290338
} else {
291-
safeRun(npmPublishCmd);
339+
console.log('The "bowerRepo" is not set in package.json. Not publishing bower.'.yellow);
292340
}
293-
294-
console.log('Released: '.cyan + 'npm package'.green);
295341
}
296342

297-
// bower
298-
if (isPrivate) {
299-
console.log('Package is private, skipping bower release'.yellow);
300-
} else if (bowerRepo) {
301-
console.log('Releasing: '.cyan + 'bower package'.green);
302-
rm('-rf', tmpBowerRepo);
303-
run(`git clone ${bowerRepo} ${tmpBowerRepo}`);
304-
pushd(tmpBowerRepo);
305-
rm('-rf', ls(tmpBowerRepo).filter(file => file !== '.git')); // delete all but `.git` dir
306-
cp('-R', bowerRoot, tmpBowerRepo);
307-
safeRun('git add -A .');
308-
safeRun(`git commit -m "Release ${vVersion}"`);
309-
safeRun(`git tag -a --message=${vVersion} ${vVersion}`);
310-
safeRun('git push --follow-tags');
311-
popd();
312-
if (argv.dryRun) {
313-
console.log(`[rm -rf ${tmpBowerRepo}]`.grey, 'DRY RUN'.magenta);
314-
} else {
315-
rm('-rf', tmpBowerRepo);
316-
}
317-
console.log('Released: '.cyan + 'bower package'.green);
318-
} else {
319-
console.log('The "bowerRepo" is not set in package.json. Not publishing bower.'.yellow);
343+
// documents site
344+
if (!isPrivate && docsRepo) {
345+
console.log('Releasing: '.cyan + 'documents site'.green);
346+
releaseAdRepo(docsRepo, docsRoot, tmpDocsRepo, vVersion);
347+
console.log('Documents site has been released'.green);
320348
}
321349

322350
console.log('Version '.cyan + `v${newVersion}`.green + ' released!'.cyan);

0 commit comments

Comments
 (0)