Skip to content

Commit

Permalink
Automate release process (#1376)
Browse files Browse the repository at this point in the history
* Autogenerate Changelog

* Remove unused CI config files

* Update version script

* Include Head-Tag as last version in changelog

* Update handling of HEAD

* Automatically checking changelog.md after version update

* Remove unused console.log

* Add preversion script

* Add release workflow

* Update release workflow
  • Loading branch information
PKief committed Jan 23, 2022
1 parent 378511a commit 5d7da79
Show file tree
Hide file tree
Showing 9 changed files with 1,234 additions and 1,517 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Release + Publish

on:
workflow_dispatch:
inputs:
versionChange:
type: choice
description: Select the version change
requried: true
options:
- major
- minor
- patch

jobs:
release:
runs-on: ubuntu-latest
env:
VERSION_CHANGE: ${{ github.event.inputs.versionChange }}
steps:
- name: Checkout 🛎️
uses: actions/checkout@v2
- name: Setup Node.js ⚙️
uses: actions/setup-node@v2
with:
node-version: 'lts/*'
- name: Install node_modules 📦
run: |
npm install
npm install --global vsce
- name: Update version ↗
run: npm version ${{ env.VERSION_CHANGE }}
- name: Get version 🔍
run: |
NODE_VERSION=$(node -p -e "require('./package.json').version")
echo VERSION=$NODE_VERSION >> $GITHUB_ENV
- name: Build ⚒️
run: vsce package
- name: Push tags 📌
run: git push --follow-tags
- name: Release ${{ env.VERSION }} 🔆
uses: softprops/action-gh-release@v1
with:
files: material-icon-theme-${{ env.VERSION }}.vsix
tag_name: v${{ env.VERSION }}
name: Material Icon Theme v${{ env.VERSION }}
generate_release_notes: true
- name: Publish to Open VSX Registry 🌐
uses: HaaLeo/publish-vscode-extension@v1
with:
pat: ${{ secrets.OPEN_VSX_TOKEN }}
extensionFile: material-icon-theme-${{ env.VERSION }}.vsix
- name: Publish to Visual Studio Marketplace 🌐
uses: HaaLeo/publish-vscode-extension@v1
with:
pat: ${{ secrets.VS_MARKETPLACE_TOKEN }}
registryUrl: https://marketplace.visualstudio.com
extensionFile: material-icon-theme-${{ env.VERSION }}.vsix
23 changes: 0 additions & 23 deletions .travis.yml

This file was deleted.

2 changes: 0 additions & 2 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ src/**
scripts/**
**/*.map
.gitignore
.travis.yml
appveyor.yml
tsconfig.json
tslint.json
images/**
Expand Down
2,506 changes: 1,034 additions & 1,472 deletions CHANGELOG.md

Large diffs are not rendered by default.

20 changes: 0 additions & 20 deletions appveyor.yml

This file was deleted.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"preview": "ts-node ./src/scripts/preview",
"svgo": "svgo -i icons -o icons -q",
"test": "node ./out/test/runTest.js",
"preversion": "npm run contributors && git add images/contributors.png && npm run preview && git add images/fileIcons.png && git add images/folderIcons.png",
"version": "ts-node ./src/scripts/changelog/index && git add CHANGELOG.md",
"vscode:prepublish": "npm run lint && npm run compile && npm run package-web"
},
"publisher": "PKief",
Expand Down
5 changes: 5 additions & 0 deletions src/scripts/changelog/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const config = {
repoName: 'https://github.com/PKief/vscode-material-icon-theme',
blacklistPattern: /Release/,
outputFilename: 'CHANGELOG.md',
};
122 changes: 122 additions & 0 deletions src/scripts/changelog/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { exec } from 'child_process';
import { writeFile } from 'fs';
import { promisify } from 'util';
import { config } from './config';
import { Commit, TagGroup } from './models';

const execAsync = promisify(exec);
const writeFileAsync = promisify(writeFile);

const getReleaseTags = async (): Promise<
{
creatorDate: string;
tag: string;
}[]
> => {
const command = `git tag -l --sort=-creatordate --format=%(creatordate:short),%(refname:short)`;
const result = await execAsync(command);
return result.stdout
.split('\n')
.filter((tag) => !!tag)
.map((tag) => {
const value = tag.split(',');
return {
creatorDate: value[0],
tag: value[1],
};
});
};

const getReleaseCommits = async (
toTag: string,
fromTag: string
): Promise<Commit[]> => {
const separator = '_||_';
const command = `git log ${fromTag}..${toTag} --no-merges --pretty=format:"%ad${separator}%h${separator}%ae${separator}%s"`;
const logResult = await execAsync(command);
return logResult.stdout
.split('\n')
.filter((message) => !new RegExp(config.blacklistPattern).test(message))
.map((message) => {
const data = message.split(separator);
return {
date: data[0],
hash: data[1],
author: data[2],
subject: data[3],
} as Commit;
});
};

const groupCommitsByTags = async () => {
const releaseCommits = [];

const headTag = {
creatorDate: new Date().toISOString().slice(0, 10),
tag: 'HEAD',
};
const allTags = [headTag, ...(await getReleaseTags())];
for await (const [index, value] of allTags.slice(0, -1).entries()) {
const previousTag = allTags[index + 1].tag;
const commits = await getReleaseCommits(value.tag, previousTag);
releaseCommits.push({
commits,
previousTag,
tag: value.tag,
date: new Date(value.creatorDate),
});
}
return releaseCommits;
};

const ticketRecognition = (commitMessage: string): string | undefined => {
return commitMessage.match(/\((?<ticket>#\d+)\)/)?.groups?.ticket;
};

const formatDate = (date: Date) => {
return date.toLocaleString('en', {
month: 'long',
day: 'numeric',
year: 'numeric',
});
};

const createMarkdown = (title: string, tagGroups: TagGroup[]) => {
return (
title +
tagGroups.reduce((result, group) => {
const subtitle = `\n#### [${
group.tag === 'HEAD' ? 'v' + process.env.npm_package_version : group.tag
}](${config.repoName}/compare/${group.tag}...${group.previousTag})\n`;
const date = `\n> ${formatDate(group.date)}\n\n`;
const commits = group.commits.reduce((result, commit) => {
const ticket = ticketRecognition(commit.subject);
let reference = '';
if (ticket) {
commit.subject = commit.subject.replace(`(${ticket})`, ''); // remove ticket number
reference = `[\`${ticket}\`](${config.repoName}/pull/${ticket.slice(
1
)})`;
} else {
reference = `[\`${commit.hash}\`](${config.repoName}/commit/${commit.hash})`;
}
return (
result + `- ${commit.subject.replace(/[<<]/, '&lt;')} ${reference}\n`
);
}, '');
return result + subtitle + date + commits;
}, '')
);
};

const run = async () => {
const tagGroups = await groupCommitsByTags();

const title =
'### Changelog \n\n All notable changes to this project will be documented in this file. Dates are displayed in UTC.\n\n';
const output = createMarkdown(title, tagGroups);

await writeFileAsync(config.outputFilename, output);
};

run();
13 changes: 13 additions & 0 deletions src/scripts/changelog/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface Commit {
date: string;
hash: string;
author: string;
subject: string;
}

export interface TagGroup {
commits: Commit[];
previousTag: string;
tag: string;
date: Date;
}

0 comments on commit 5d7da79

Please sign in to comment.