PageSourceSearch

https://gulpjs.com/assets/js/e2f59c9e.b3813bae.js

js gulpjs.com collected 2026-09-24 07:27:30 UTC 5,422 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkgulpjs_github_io=self.webpackChunkgulpjs_github_io||[]).push([[123],{617:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var o=t(4848),s=t(8453);const a={id:"automate-releases",title:"Automate Releases",hide_title:!0,sidebar_label:"Automate Releases"},i="Automate Releases",r={id:"recipes/automate-releases",title:"Automate Releases",description:"If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release.",source:"@site/docs/recipes/automate-releases.md",sourceDirName:"recipes",slug:"/recipes/automate-releases",permalink:"/docs/en/recipes/automate-releases",draft:!1,unlisted:!1,tags:[],version:"current",frontMatter:{id:"automate-releases",title:"Automate Releases",hide_title:!0,sidebar_label:"Automate Releases"},sidebar:"docs",previous:{title:"Creating Custom Registries",permalink:"/docs/en/advanced/creating-custom-registries"},next:{title:"Concepts",permalink:"/docs/en/api/concepts"}},c={},l=[];function u(e){const n={a:"a",code:"code",h1:"h1",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"automate-releases",children:"Automate Releases"}),"\n",(0,o.jsx)(n.p,{children:"If your project follows a semantic versioning, it may be a good idea to automatize the steps needed to do a release.\nThe recipe below bumps the project version, commits the changes to git and creates a new GitHub release."}),"\n",(0,o.jsxs)(n.p,{children:["For publishing a GitHub release you'll need to ",(0,o.jsx)(n.a,{href:"https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token",children:"create a personal access token"})," and add it to your project. However, we don't want to commit it, so we'll use ",(0,o.jsx)(n.a,{href:"https://www.npmjs.com/package/dotenv",children:(0,o.jsx)(n.code,{children:"dotenv"})})," to load it from a git-ignored ",(0,o.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"GH_TOKEN=ff34885...\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Don't forget to add ",(0,o.jsx)(n.code,{children:".env"})," to your ",(0,o.jsx)(n.code,{children:".gitignore"}),"."]}),"\n",(0,o.jsx)(n.p,{children:"Next, install all the necessary dependencies for this recipe:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"npm install --save-dev conventional-recommended-bump conventional-changelog-cli conventional-github-releaser dotenv execa\n"})}),"\n",(0,o.jsx)(n.p,{children:"Based on your environment, setup and preferences, your release workflow might look something like this:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"const gulp = require('gulp');\nconst conventionalRecommendedBump = require('conventional-recommended-bump');\nconst conventionalGithubReleaser = require('conventional-github-releaser');\nconst execa = require('execa');\nconst fs = require('fs');\nconst { promisify } = require('util');\nconst dotenv = require('dotenv');\n\n// load environment variables\nconst result = dotenv.config();\n\nif (result.error) {\n  throw result.error;\n}\n\n// Conventional Changelog preset\nconst preset = 'angular';\n// print output of commands into the terminal\nconst stdio = 'inherit';\n\nasync function bumpVersion() {\n  // get recommended version bump based on commits\n  const { releaseType } = await promisify(conventionalRecommendedBump)({ preset });\n  // bump version without committing and tagging\n  await execa('npm', ['version', releaseType, '--no-git-tag-version'], {\n    stdio,\n  });\n}\n\nasync function changelog() {\n  await execa(\n    'npx',\n    [\n      'conventional-changelog',\n      '--preset',\n      preset,\n      '--infile',\n      'CHANGELOG.md',\n      '--same-file',\n    ],\n    { stdio }\n  );\n}\n\nasync function commitTagPush() {\n  // even though we could get away with \"require\" in this case, we're taking the safe route\n  // because \"require\" caches the value, so if we happen to use \"require\" again somewhere else\n  // we wouldn't get the current value, but the value of the last time we called \"require\"\n  const { version } = JSON.parse(await promisify(fs.readFile)('package.json'));\n  const commitMsg = `chore: release ${version}`;\n  await execa('git', ['add', '.'], { stdio });\n  await execa('git', ['commit', '--message', commitMsg], { stdio });\n  await execa('git', ['tag', `v${version}`], { stdio });\n  await execa('git', ['push', '--follow-tags'], { stdio });\n}\n\nfunction githubRelease(done) {\n  conventionalGithubReleaser(\n    { type: 'oauth', token: process.env.GH_TOKEN },\n    { preset },\n    done\n  );\n}\n\nexports.release = gulp.series(\n  bumpVersion,\n  changelog,\n  commitTagPush,\n  githubRelease\n
1);\n"})})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(6540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.