chore(release): create a github release on new version
This commit is contained in:
		
							parent
							
								
									85cb0ffabd
								
							
						
					
					
						commit
						dbad7730f9
					
				
							
								
								
									
										56
									
								
								.github/workflows/releases.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										56
									
								
								.github/workflows/releases.yml
									
									
									
									
										vendored
									
									
								
							| @ -46,3 +46,59 @@ jobs: | |||||||
|             corentinth/it-tools:${{ env.RELEASE_VERSION }} |             corentinth/it-tools:${{ env.RELEASE_VERSION }} | ||||||
|             ghcr.io/corentinth/it-tools:latest |             ghcr.io/corentinth/it-tools:latest | ||||||
|             ghcr.io/corentinth/it-tools:${{ env.RELEASE_VERSION}} |             ghcr.io/corentinth/it-tools:${{ env.RELEASE_VERSION}} | ||||||
|  | 
 | ||||||
|  |   github-release: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     needs: docker-release | ||||||
|  |     steps: | ||||||
|  |       - name: Get release version | ||||||
|  |         run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV | ||||||
|  | 
 | ||||||
|  |       - name: Checkout | ||||||
|  |         uses: actions/checkout@v3 | ||||||
|  | 
 | ||||||
|  |       - run: corepack enable | ||||||
|  | 
 | ||||||
|  |       - uses: actions/setup-node@v3 | ||||||
|  |         with: | ||||||
|  |           node-version: 16 | ||||||
|  |           cache: 'pnpm' | ||||||
|  | 
 | ||||||
|  |       - name: Install dependencies | ||||||
|  |         run: pnpm i | ||||||
|  | 
 | ||||||
|  |       - name: Build the app | ||||||
|  |         run: pnpm build | ||||||
|  | 
 | ||||||
|  |       - name: Zip the app | ||||||
|  |         run: zip -r it-tools-${{ env.RELEASE_VERSION }}.zip dist/* | ||||||
|  | 
 | ||||||
|  |       - name: Get changelog | ||||||
|  |         id: changelog | ||||||
|  |         run: | | ||||||
|  |           EOF=$(openssl rand -hex 8) | ||||||
|  |           echo "changelog<<$EOF" >> $GITHUB_OUTPUT | ||||||
|  |           node ./scripts/getLatestChangelog.mjs >> $GITHUB_OUTPUT | ||||||
|  |           echo "$EOF" >> $GITHUB_OUTPUT | ||||||
|  | 
 | ||||||
|  |       - name: Create Release | ||||||
|  |         uses: softprops/action-gh-release@v1 | ||||||
|  |         with: | ||||||
|  |           token: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |           files: it-tools-${{ env.RELEASE_VERSION }}.zip | ||||||
|  |           tag_name: v${{ env.RELEASE_VERSION }} | ||||||
|  |           draft: true | ||||||
|  |           prerelease: false | ||||||
|  |           body: | | ||||||
|  |             ## Docker images | ||||||
|  | 
 | ||||||
|  |             - Docker Hub | ||||||
|  |               - `corentinth/it-tools:latest` | ||||||
|  |               - `corentinth/it-tools:${{ env.RELEASE_VERSION }}` | ||||||
|  |             - GitHub Container Registry | ||||||
|  |               - `ghcr.io/corentinth/it-tools:latest` | ||||||
|  |               - `ghcr.io/corentinth/it-tools:${{ env.RELEASE_VERSION}}` | ||||||
|  | 
 | ||||||
|  |             ## Changelog | ||||||
|  | 
 | ||||||
|  |             ${{ steps.changelog.outputs.changelog }} | ||||||
|  | |||||||
							
								
								
									
										36
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -2,6 +2,42 @@ | |||||||
| 
 | 
 | ||||||
| All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. | ||||||
| 
 | 
 | ||||||
|  | ## Version 2023.04.14-f9b77b7 | ||||||
|  | 
 | ||||||
|  | ### Features | ||||||
|  | - **new-tool**: http status codes (8355bd2) | ||||||
|  | 
 | ||||||
|  | ### Refactoring | ||||||
|  | - **uuid-generator**: prevent NaN in quantity (6fb4994) | ||||||
|  | 
 | ||||||
|  | ### Chores | ||||||
|  | - **release**: create a github release on new version (f9b77b7) | ||||||
|  | - **version**: reset CHANGELOG content to support new format (85cb0ff) | ||||||
|  | 
 | ||||||
|  | ## Version 2023.04.14-2f0d239 | ||||||
|  | 
 | ||||||
|  | ### Features | ||||||
|  | - **new-tool**: http status codes (8355bd2) | ||||||
|  | 
 | ||||||
|  | ### Refactoring | ||||||
|  | - **uuid-generator**: prevent NaN in quantity (6fb4994) | ||||||
|  | 
 | ||||||
|  | ### Chores | ||||||
|  | - **release**: create a github release on new version (2f0d239) | ||||||
|  | - **version**: reset CHANGELOG content to support new format (85cb0ff) | ||||||
|  | 
 | ||||||
|  | ## Version 2023.04.14-474cae4 | ||||||
|  | 
 | ||||||
|  | ### Features | ||||||
|  | - **new-tool**: http status codes (8355bd2) | ||||||
|  | 
 | ||||||
|  | ### Refactoring | ||||||
|  | - **uuid-generator**: prevent NaN in quantity (6fb4994) | ||||||
|  | 
 | ||||||
|  | ### Chores | ||||||
|  | - **release**: create a github release on new version (474cae4) | ||||||
|  | - **version**: reset CHANGELOG content to support new format (85cb0ff) | ||||||
|  | 
 | ||||||
| ## Version v2023.4.13-dce9ff9 | ## Version v2023.4.13-dce9ff9 | ||||||
| 
 | 
 | ||||||
| _Diff not available_ | _Diff not available_ | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "it-tools", |   "name": "it-tools", | ||||||
|   "version": "2023.4.13-dce9ff9", |   "version": "2023.4.14-f9b77b7", | ||||||
|   "description": "Collection of handy online tools for developers, with great UX. ", |   "description": "Collection of handy online tools for developers, with great UX. ", | ||||||
|   "keywords": [ |   "keywords": [ | ||||||
|     "productivity", |     "productivity", | ||||||
| @ -30,7 +30,7 @@ | |||||||
|     "typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false", |     "typecheck": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false", | ||||||
|     "lint": "eslint src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore", |     "lint": "eslint src --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore", | ||||||
|     "script:create-new-tool": "node scripts/create-tool.mjs", |     "script:create-new-tool": "node scripts/create-tool.mjs", | ||||||
|     "release": "standard-version" |     "release": "node ./scripts/release.mjs" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@it-tools/bip39": "^0.0.4", |     "@it-tools/bip39": "^0.0.4", | ||||||
| @ -101,6 +101,7 @@ | |||||||
|     "@vue/test-utils": "^2.3.2", |     "@vue/test-utils": "^2.3.2", | ||||||
|     "@vue/tsconfig": "^0.1.3", |     "@vue/tsconfig": "^0.1.3", | ||||||
|     "c8": "^7.13.0", |     "c8": "^7.13.0", | ||||||
|  |     "consola": "^3.0.2", | ||||||
|     "eslint": "^8.38.0", |     "eslint": "^8.38.0", | ||||||
|     "eslint-config-prettier": "^8.8.0", |     "eslint-config-prettier": "^8.8.0", | ||||||
|     "eslint-import-resolver-typescript": "^3.5.5", |     "eslint-import-resolver-typescript": "^3.5.5", | ||||||
| @ -109,7 +110,6 @@ | |||||||
|     "jsdom": "^19.0.0", |     "jsdom": "^19.0.0", | ||||||
|     "less": "^4.1.3", |     "less": "^4.1.3", | ||||||
|     "prettier": "^2.8.7", |     "prettier": "^2.8.7", | ||||||
|     "standard-version": "^9.5.0", |  | ||||||
|     "start-server-and-test": "^1.15.4", |     "start-server-and-test": "^1.15.4", | ||||||
|     "typescript": "~4.5.5", |     "typescript": "~4.5.5", | ||||||
|     "unocss": "^0.50.8", |     "unocss": "^0.50.8", | ||||||
| @ -121,6 +121,7 @@ | |||||||
|     "vite-svg-loader": "^3.6.0", |     "vite-svg-loader": "^3.6.0", | ||||||
|     "vitest": "^0.13.1", |     "vitest": "^0.13.1", | ||||||
|     "vue-tsc": "^0.31.4", |     "vue-tsc": "^0.31.4", | ||||||
|     "workbox-window": "^6.5.4" |     "workbox-window": "^6.5.4", | ||||||
|  |     "zx": "^7.2.1" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										942
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										942
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										6
									
								
								scripts/getLatestChangelog.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								scripts/getLatestChangelog.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | import { readFile } from 'fs/promises'; | ||||||
|  | 
 | ||||||
|  | const changelogContent = await readFile('./CHANGELOG.md', 'utf-8'); | ||||||
|  | const [, lastChangelog] = changelogContent.split(/^## .*$/gm); | ||||||
|  | 
 | ||||||
|  | console.log(lastChangelog.trim()); | ||||||
							
								
								
									
										57
									
								
								scripts/release.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								scripts/release.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | import { $, argv } from 'zx'; | ||||||
|  | import { consola } from 'consola'; | ||||||
|  | import { rawCommitsToMarkdown } from './shared/commits.mjs'; | ||||||
|  | import { addToChangelog } from './shared/changelog.mjs'; | ||||||
|  | 
 | ||||||
|  | $.verbose = false; | ||||||
|  | 
 | ||||||
|  | const isDryRun = argv['dry-run'] ?? false; | ||||||
|  | 
 | ||||||
|  | const now = new Date(); | ||||||
|  | const currentShortSha = (await $`git rev-parse --short HEAD`).stdout.trim(); | ||||||
|  | 
 | ||||||
|  | const calver = now.toISOString().slice(0, 10).replace(/-/g, '.'); | ||||||
|  | const version = `${calver}-${currentShortSha}`; | ||||||
|  | 
 | ||||||
|  | const { stdout: rawCommits } = await $`git log --pretty=oneline $(git describe --tags --abbrev=0)..HEAD`; | ||||||
|  | 
 | ||||||
|  | const markdown = rawCommitsToMarkdown({ rawCommits }); | ||||||
|  | 
 | ||||||
|  | consola.info(`Changelog: \n\n${markdown}\n\n`); | ||||||
|  | 
 | ||||||
|  | if (isDryRun) { | ||||||
|  |   consola.info(`[dry-run] Not creating version nor tag`); | ||||||
|  |   consola.info('Aborting'); | ||||||
|  |   process.exit(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const shouldContinue = await consola.prompt( | ||||||
|  |   'This script will create a new version and tag, and update the changelog. Continue?', | ||||||
|  |   { | ||||||
|  |     type: 'confirm', | ||||||
|  |   }, | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | if (!shouldContinue) { | ||||||
|  |   consola.info('Aborting'); | ||||||
|  |   process.exit(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | consola.info('Updating changelog'); | ||||||
|  | await addToChangelog({ changelog: markdown, version }); | ||||||
|  | consola.success('Changelog updated'); | ||||||
|  | 
 | ||||||
|  | try { | ||||||
|  |   consola.info('Committing changelog changes'); | ||||||
|  |   await $`git add CHANGELOG.md`; | ||||||
|  |   await $`git commit -m "docs(changelog): update changelog for ${version}"`; | ||||||
|  |   consola.success('Changelog changes committed'); | ||||||
|  | 
 | ||||||
|  |   consola.info('Creating version and tag'); | ||||||
|  |   await $`npm version ${version} -m "chore(version): release ${version}"`; | ||||||
|  |   consola.info('Npm version released with tag'); | ||||||
|  | } catch (error) { | ||||||
|  |   consola.error(error); | ||||||
|  |   consola.info('Aborting'); | ||||||
|  |   process.exit(1); | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								scripts/shared/changelog.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								scripts/shared/changelog.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | import { readFile, writeFile } from 'fs/promises'; | ||||||
|  | 
 | ||||||
|  | export { addToChangelog }; | ||||||
|  | 
 | ||||||
|  | async function addToChangelog({ changelog, version, changelogPath = './CHANGELOG.md' }) { | ||||||
|  |   const changelogContent = await readFile(changelogPath, 'utf-8'); | ||||||
|  |   const versionTitle = `## Version ${version}`; | ||||||
|  | 
 | ||||||
|  |   if (changelogContent.includes(versionTitle)) { | ||||||
|  |     throw new Error(`Version ${version} already exists in the changelog`); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   const newChangeLogContent = changelogContent.replace('## ', `${versionTitle}\n\n${changelog}\n\n## `); | ||||||
|  |   await writeFile(changelogPath, newChangeLogContent, 'utf-8'); | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								scripts/shared/commits.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								scripts/shared/commits.mjs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | import _ from 'lodash'; | ||||||
|  | 
 | ||||||
|  | export { rawCommitsToMarkdown }; | ||||||
|  | 
 | ||||||
|  | const commitScopesToHumanReadable = { | ||||||
|  |   build: 'Build system', | ||||||
|  |   chore: 'Chores', | ||||||
|  |   ci: 'Continuous integration', | ||||||
|  |   docs: 'Documentation', | ||||||
|  |   feat: 'Features', | ||||||
|  |   fix: 'Bug fixes', | ||||||
|  |   infra: 'Infrastucture', | ||||||
|  |   perf: 'Performance', | ||||||
|  |   refactor: 'Refactoring', | ||||||
|  |   test: 'Tests', | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const commitTypesOrder = ['feat', 'fix', 'perf', 'refactor', 'test', 'build', 'ci', 'chore', 'other']; | ||||||
|  | 
 | ||||||
|  | const getCommitTypeSortIndex = (type) => | ||||||
|  |   commitTypesOrder.includes(type) ? commitTypesOrder.indexOf(type) : commitTypesOrder.length; | ||||||
|  | 
 | ||||||
|  | function parseCommitLine(commit) { | ||||||
|  |   const [sha, ...splittedRawMessage] = commit.trim().split(' '); | ||||||
|  |   const rawMessage = splittedRawMessage.join(' '); | ||||||
|  |   const { type, scope, subject } = /^(?<type>.*?)(\((?<scope>.*)\))?: ?(?<subject>.+)$/.exec(rawMessage)?.groups ?? {}; | ||||||
|  | 
 | ||||||
|  |   return { | ||||||
|  |     sha: sha.slice(0, 7), | ||||||
|  |     type: type ?? 'other', | ||||||
|  |     scope, | ||||||
|  |     subject: subject ?? rawMessage, | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function commitSectionsToMarkdown({ type, commits }) { | ||||||
|  |   return [ | ||||||
|  |     `### ${commitScopesToHumanReadable[type] ?? _.capitalize(type)}`, | ||||||
|  |     ...commits.map(({ sha, scope, subject }) => ['-', scope ? `**${scope}**:` : '', subject, `(${sha})`].join(' ')), | ||||||
|  |   ].join('\n'); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function rawCommitsToMarkdown({ rawCommits }) { | ||||||
|  |   return _.chain(rawCommits) | ||||||
|  |     .trim() | ||||||
|  |     .split('\n') | ||||||
|  |     .map(parseCommitLine) | ||||||
|  |     .groupBy('type') | ||||||
|  |     .map((commits, type) => ({ type, commits })) | ||||||
|  |     .sortBy(({ type }) => getCommitTypeSortIndex(type)) | ||||||
|  |     .map(commitSectionsToMarkdown) | ||||||
|  |     .join('\n\n') | ||||||
|  |     .value(); | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user