Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(en): merge gulp/source into gulp/cn @ 6bb96aba #9

Open
wants to merge 29 commits into
base: cn
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7c6a91f
Add Decojent as a new org sponsor (#124)
phated Jul 29, 2020
8ae19df
Add a package-lock because docusaurus had breaking changes
phated Jul 28, 2020
8274253
Utilize OneGraph to join GitHub Sponsors & OpenCollective
phated Jul 28, 2020
c4cd0a2
Merge branch 'source' of https://github.com/gulpjs/gulpjs.github.io i…
docschina-bot Aug 3, 2020
ba40a85
Disable Navbar search on Plugins page to focus on plugin search (#125)
Aug 4, 2020
f4959db
Fix weighting to remove some sketchy packages
phated Aug 4, 2020
7141598
Add code comment linking to npm search API docs
phated Aug 4, 2020
d0c3bf3
useLocation & formatting
phated Aug 4, 2020
487199c
Merge branch 'source' of https://github.com/gulpjs/gulpjs.github.io i…
docschina-bot Aug 10, 2020
bd278d5
Add special styling for deprecated plugins in search (closes $113) (#…
Aug 23, 2020
cd4b5ca
Add advanced section to the sidebar
phated Aug 24, 2020
826e792
Merge branch 'source' of https://github.com/gulpjs/gulpjs.github.io i…
docschina-bot Aug 24, 2020
eb3ed48
docs(en): fetch all
docschina-bot Aug 28, 2020
abe0ac3
Remove company that ended sponsorship
phated Oct 20, 2020
4fe7b9a
Add first recipe to sidebar
phated Oct 21, 2020
e1cc1ea
docs(en): fetch all
docschina-bot Oct 23, 2020
3797585
Fix: Show copy to clipboard button (#130)
Oct 23, 2020
0ffbe8b
Merge branch 'source' of https://github.com/gulpjs/gulpjs.github.io i…
docschina-bot Oct 26, 2020
7d3d696
docs(en): fetch all
docschina-bot Jan 15, 2021
ac31770
Fix: Cleanup hero svg (#132)
jagdish7908 Jan 21, 2021
c8af31d
Merge branch 'source' of https://github.com/gulpjs/gulpjs.github.io i…
docschina-bot Jan 25, 2021
ba6bb66
docs(en): fetch all
docschina-bot Feb 12, 2021
6e3e339
Upgrade Docusaurus to alpha.70 (#133)
Apr 7, 2021
929a2bf
fix deploy
phated Apr 7, 2021
d7b89dd
no follow too
phated Apr 9, 2021
3de4272
add wordtips sponsor
phated Apr 9, 2021
87d3665
Merge branch 'source' of https://github.com/gulpjs/gulpjs.github.io i…
docschina-bot Apr 12, 2021
6bb96ab
docs(en): fetch all
docschina-bot Apr 16, 2021
f970cca
docs(en): merging all conflicts
docschina-bot Apr 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Deploy
# Use the SHA because I am untrustworthy
# TODO: We probably should fork any non-GitHub owned actions
uses: peaceiris/actions-gh-pages@1828d86
uses: peaceiris/actions-gh-pages@1828d864aeb7ba79a37f40035aa6d0b7ff66254f
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ yarn-error.log*
*.log

# lock
package-lock.json
yarn.lock

# generated
Expand Down
2 changes: 1 addition & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
package-lock=false
package-lock=true
loglevel=error
207 changes: 207 additions & 0 deletions docs/advanced/creating-custom-registries.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
---
id: creating-custom-registries
title: Creating Custom Registries
hide_title: true
sidebar_label: Creating Custom Registries
---

# Creating Custom Registries

Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality. Registries are registered using [`registry()`][registry-api-docs].

## Structure

In order to be accepted by gulp, custom registries must follow a specific format.

```js
// as a function
function TestRegistry() {}

TestRegistry.prototype.init = function (gulpInst) {}
TestRegistry.prototype.get = function (name) {}
TestRegistry.prototype.set = function (name, fn) {}
TestRegistry.prototype.tasks = function () {}

// as a class
class TestRegistry {
init(gulpInst) {}

get(name) {}

set(name, fn) {}

tasks() {}
}
```

If a registry instance passed to `registry()` doesn't have all four methods, an error will be thrown.

## Registration

If we want to register our example registry from above, we will need to pass an instance of it to `registry()`.

```js
const { registry } = require('gulp');

// ... TestRegistry setup code

// good!
registry(new TestRegistry())

// bad!
registry(TestRegistry())
// This will trigger an error: 'Custom registries must be instantiated, but it looks like you passed a constructor'
```

## Methods

### `init(gulpInst)`

The `init()` method of a registry is called at the very end of the `registry()` function. The gulp instance passed as the only argument (`gulpInst`) can be used to pre-define tasks using
`gulpInst.task(taskName, fn)`.

#### Parameters

| parameter | type | note |
|:---------:|:----:|------|
| gulpInst | object | Instance of gulp. |

### `get(name)`

The `get()` method receives a task `name` for the custom registry to resolve and return, or `undefined` if no task with that name exists.

#### Parameters

| parameter | type | note |
|:---------:|:----:|------|
| name | string | Name of the task to be retrieved. |

### `set(name, fn)`

The `set()` method receives a task `name` and `fn`. This is called internally by `task()` to provide user-registered tasks to custom registries.

#### Parameters

| parameter | type | note |
|:---------:|:----:|------|
| name | string | Name of the task to be set. |
| fn | function | Task function to be set. |

### `tasks()`

Must return an object listing all tasks in the registry.

## Use Cases

### Sharing Tasks

To share common tasks with all your projects, you can expose an `init` method on the registry and it will receive an instance of gulp as the only argument. You can then use `gulpInst.task(name, fn)` to register pre-defined tasks.

For example, you might want to share a `clean` task:

```js
const fs = require('fs');
const util = require('util');

const DefaultRegistry = require('undertaker-registry');
const del = require('del');

function CommonRegistry(opts){
DefaultRegistry.call(this);

opts = opts || {};

this.buildDir = opts.buildDir || './build';
}

util.inherits(CommonRegistry, DefaultRegistry);

CommonRegistry.prototype.init = function(gulpInst) {
const buildDir = this.buildDir;
const exists = fs.existsSync(buildDir);

if(exists){
throw new Error('Cannot initialize common tasks. ' + buildDir + ' directory exists.');
}

gulpInst.task('clean', function(){
return del([buildDir]);
});
}

module.exports = CommonRegistry;
```

Then to use it in a project:

```js
const { registry, series, task } = require('gulp');
const CommonRegistry = require('myorg-common-tasks');

registry(new CommonRegistry({ buildDir: '/dist' }));

task('build', series('clean', function build(cb) {
// do things
cb();
}));
```

### Sharing Functionality

By controlling how tasks are added to the registry, you can decorate them.

For example, if you wanted all tasks to share some data, you can use a custom registry to bind them to that data. Be sure to return the altered task, as per the description of registry methods above:

```js
const { registry, series, task } = require('gulp');
const util = require('util');
const DefaultRegistry = require('undertaker-registry');

// Some task defined somewhere else
const BuildRegistry = require('./build.js');
const ServeRegistry = require('./serve.js');

function ConfigRegistry(config){
DefaultRegistry.call(this);
this.config = config;
}

util.inherits(ConfigRegistry, DefaultRegistry);

ConfigRegistry.prototype.set = function set(name, fn) {
var bound = fn.bind(this.config);
// Preserve internal properties and task metadata.
var task = Object.assign(bound, fn);
// The `DefaultRegistry` uses `this._tasks` for storage.
this._tasks[name] = task;
return task;
};

registry(new BuildRegistry());
registry(new ServeRegistry());

// `registry` will reset each task in the registry with
// `ConfigRegistry.prototype.set` which will bind them to the config object.
registry(new ConfigRegistry({
src: './src',
build: './build',
bindTo: '0.0.0.0:8888'
}));

task('default', series('clean', 'build', 'serve', function(cb) {
console.log('Server bind to ' + this.bindTo);
console.log('Serving' + this.build);
cb();
}));
```

## Examples

* [undertaker-registry][undertaker-registry-example]: The Gulp 4 default registry.
* [undertaker-common-tasks][undertaker-common-tasks-example]: Proof-of-concept custom registry that pre-defines tasks.
* [undertaker-task-metadata][undertaker-task-metadata-example]: Proof-of-concept custom registry that attaches metadata to each task.

[registry-api-docs]: ../api/registry.md
[undertaker-registry-example]: https://github.com/gulpjs/undertaker-registry
[undertaker-common-tasks-example]: https://github.com/gulpjs/undertaker-common-tasks
[undertaker-task-metadata-example]: https://github.com/gulpjs/undertaker-task-metadata
33 changes: 26 additions & 7 deletions docs/api/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ sidebar_label: registry()

# registry()


Allows custom registries to be plugged into the task system, which can provide shared tasks or augmented functionality.

**Note:** Only tasks registered with `task()` will be provided to the custom registry. The task functions passed directly to `series()` or `parallel()` will not be provided - if you need to customize the registry behavior, compose tasks with string references.
Expand Down Expand Up @@ -50,14 +49,34 @@ If a `registryInstance` is passed, nothing will be returned. If no arguments are

### Errors

When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message, "Custom registries must be instantiated, but it looks like you passed a constructor".
#### Incorrect parameter

When a constructor (instead of an instance) is passed as `registryInstance`, throws an error with the message:

> Custom registries must be instantiated, but it looks like you passed a constructor.

#### Missing `get` method

When a registry without a `get` method is passed as `registryInstance`, throws an error with the message:

> Custom registry must have `get` function.

#### Missing `set` method

When a registry without a `set` method is passed as `registryInstance`, throws an error with the message:

> Custom registry must have `set` function.

#### Missing `init` method

When a registry without an `init` method is passed as `registryInstance`, throws an error with the message:

When a registry without a `get` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `get` function".
> Custom registry must have `init` function"

When a registry without a `set` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `set` function".
#### Missing `tasks` method

When a registry without an `init` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `init` function"
When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message:

When a registry without a `tasks` method is passed as `registryInstance`, throws an error with the message, "Custom registry must have `tasks` function".
> Custom registry must have `tasks` function.

[creating-custom-registries]: ../documentation-missing.md
[creating-custom-registries]: ../advanced/creating-custom-registries.md
2 changes: 1 addition & 1 deletion docs/api/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Since any registered task can be run from the command line, avoid using spaces i

| parameter | type | note |
|:--------------:|:------:|-------|
| taskName | string | An alias for the task function within the the task system. Not needed when using named functions for `taskFunction`. |
| taskName | string | An alias for the task function within the task system. Not needed when using named functions for `taskFunction`. |
| taskFunction<br />**(required)** | function | A [task function][task-concepts] or composed task - generated by `series()` and `parallel()`. Ideally a named function. [Task metadata][task-metadata-section] can be attached to provide extra information to the command line. |

### Returns
Expand Down
100 changes: 100 additions & 0 deletions docs/recipes/automate-releases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
id: automate-releases
title: Automate Releases
hide_title: true
sidebar_label: Automate Releases
---

# Automate Releases

If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release.
The recipe below bumps the project version, commits the changes to git and creates a new GitHub release.

For publishing a GitHub release you'll need to [create a personal access token](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token) and add it to your project. However, we don't want to commit it, so we'll use [`dotenv`](https://www.npmjs.com/package/dotenv) to load it from a git-ignored `.env` file:

```
GH_TOKEN=ff34885...
```

Don't forget to add `.env` to your `.gitignore`.

Next, install all the necessary dependencies for this recipe:

```sh
npm install --save-dev conventional-recommended-bump conventional-changelog-cli conventional-github-releaser dotenv execa
```

Based on your environment, setup and preferences, your release workflow might look something like this:

``` js
const gulp = require('gulp');
const conventionalRecommendedBump = require('conventional-recommended-bump');
const conventionalGithubReleaser = require('conventional-github-releaser');
const execa = require('execa');
const fs = require('fs');
const { promisify } = require('util');
const dotenv = require('dotenv');

// load environment variables
const result = dotenv.config();

if (result.error) {
throw result.error;
}

// Conventional Changelog preset
const preset = 'angular';
// print output of commands into the terminal
const stdio = 'inherit';

async function bumpVersion() {
// get recommended version bump based on commits
const { releaseType } = await promisify(conventionalRecommendedBump)({ preset });
// bump version without committing and tagging
await execa('npm', ['version', releaseType, '--no-git-tag-version'], {
stdio,
});
}

async function changelog() {
await execa(
'npx',
[
'conventional-changelog',
'--preset',
preset,
'--infile',
'CHANGELOG.md',
'--same-file',
],
{ stdio }
);
}

async function commitTagPush() {
// even though we could get away with "require" in this case, we're taking the safe route
// because "require" caches the value, so if we happen to use "require" again somewhere else
// we wouldn't get the current value, but the value of the last time we called "require"
const { version } = JSON.parse(await promisify(fs.readFile)('package.json'));
const commitMsg = `chore: release ${version}`;
await execa('git', ['add', '.'], { stdio });
await execa('git', ['commit', '--message', commitMsg], { stdio });
await execa('git', ['tag', `v${version}`], { stdio });
await execa('git', ['push', '--follow-tags'], { stdio });
}

function githubRelease(done) {
conventionalGithubReleaser(
{ type: 'oauth', token: process.env.GH_TOKEN },
{ preset },
done
);
}

exports.release = gulp.series(
bumpVersion,
changelog,
commitTagPush,
githubRelease
);
```
Loading