Skip to content

Commit 71575fe

Browse files
committed
chore: first commit
0 parents  commit 71575fe

File tree

11 files changed

+1260
-0
lines changed

11 files changed

+1260
-0
lines changed

.circleci/config.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
version: 2
2+
jobs:
3+
build:
4+
docker:
5+
- image: circleci/node:8
6+
steps:
7+
- checkout
8+
- restore_cache:
9+
key: deps-{{ checksum "yarn.lock" }}
10+
- run:
11+
name: Install dependencies
12+
command: yarn install --frozen-lockfile
13+
- save_cache:
14+
key: deps-{{ checksum "yarn.lock" }}
15+
paths:
16+
- node_modules
17+
- run:
18+
name: Build
19+
command: yarn build
20+
- run:
21+
name: Lint commits
22+
command: ./src/cli.js

.github/pr-lookup.png

79.6 KB
Loading

.github/sha-lookup.png

84.1 KB
Loading

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.DS_Store
2+
3+
.vscode/
4+
node_modules/
5+
build/
6+
*.log

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Fathy Boundjadj
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
> Lint all relevant commits for a change or PR on Circle CI
2+
3+
# commitlint-circle
4+
5+
This package is a convenience wrapper around `commitlint`,
6+
providing zero-configuration linting of all relevant commits
7+
for a given change/build combination.
8+
9+
## Getting started
10+
11+
```
12+
yarn add commitlint-circle --dev
13+
```
14+
15+
```yml
16+
# .circleci/config.yml
17+
- run: yarn commitlint-circle
18+
```
19+
20+
## Screenshots
21+
22+
##### When building a PR
23+
24+
![PR Lookup](./.github/pr-lookup.png)
25+
26+
##### When building a change
27+
28+
![SHA Lookup](./.github/sha-lookup.png)

package.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "commitlint-circle",
3+
"version": "1.0.0",
4+
"main": "build/index.js",
5+
"types": "build/index.d.ts",
6+
"bin": "src/cli.js",
7+
"author": "Fathy Boundjadj <fathy.boundjadj@gmail.com>",
8+
"description": "Lint all relevant commits for a change or PR on Circle CI",
9+
"license": "MIT",
10+
"files": [
11+
"build",
12+
"src"
13+
],
14+
"scripts": {
15+
"build": "tsc",
16+
"commitmsg": "commitlint -E GIT_PARAMS"
17+
},
18+
"peerDependencies": {
19+
"@commitlint/cli": "^7.0.0"
20+
},
21+
"dependencies": {
22+
"@octokit/rest": "^15.9.4",
23+
"execa": "^0.10.0",
24+
"tslib": "^1.9.3"
25+
},
26+
"devDependencies": {
27+
"@commitlint/cli": "^7.0.0",
28+
"@commitlint/config-conventional": "^7.0.1",
29+
"@types/execa": "^0.9.0",
30+
"@types/node": "^10.5.4",
31+
"husky": "^0.14.3",
32+
"typescript": "^2.9.2"
33+
},
34+
"commitlint": {
35+
"extends": [
36+
"@commitlint/config-conventional"
37+
]
38+
}
39+
}

src/cli.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env node
2+
3+
require('..').run().catch(console.error)

src/index.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import Octokit from '@octokit/rest'
2+
import execa from 'execa'
3+
4+
const NotFound = new Error()
5+
6+
const git = (...args: string[]) => execa.stdout('git', args)
7+
8+
const checkCommit = async (...refs: string[]) =>
9+
Promise.all(
10+
refs.map(ref =>
11+
git('cat-file', '-e', ref)
12+
)
13+
)
14+
15+
const matchGithub = <T>(url: string | undefined, prop: string) => {
16+
if(!url) {
17+
throw NotFound
18+
}
19+
20+
const match = url.match(new RegExp(`github\\.com/(.+)/(.+)/${prop}/(.+)`))
21+
22+
if(!match) {
23+
throw NotFound
24+
}
25+
26+
const [_, owner, repo, data] = match
27+
28+
return {owner, repo, data}
29+
}
30+
31+
const getRangeFromPr = async () => {
32+
const {owner, repo, data: pull} = matchGithub(process.env['CIRCLE_PULL_REQUEST'], 'pull')
33+
const github = new Octokit()
34+
35+
console.log('📡 Looking up PR #%s...', pull)
36+
const {data: {base, head}} = await github.pullRequests.get(
37+
{owner, repo, number: +pull}
38+
)
39+
40+
await checkCommit(base.sha, head.sha)
41+
42+
console.log('🔀 Linting PR #%s', pull)
43+
44+
return [base.sha, head.sha]
45+
}
46+
47+
const getRangeFromCompare = async () => {
48+
const [from, to] = matchGithub(process.env['CIRCLE_COMPARE_URL'], 'compare').data.split('...')
49+
50+
await checkCommit(from, to)
51+
console.log('🎏 Linting using comparison URL %s...%s', from, to)
52+
53+
return [from, to]
54+
}
55+
56+
const getRangeFromSha = async () => {
57+
const sha = process.env['CIRCLE_SHA1']
58+
59+
if(!sha) {
60+
throw new Error('Cannot find CIRCLE_SHA1 environment variable')
61+
}
62+
63+
await checkCommit(sha)
64+
console.log('⚙️ Linting using CIRCLE_SHA1 (%s)', sha)
65+
66+
return ['origin/master', sha]
67+
}
68+
69+
const getRangeFromGit = async () => {
70+
const head = await git('rev-parse', '--verify', 'HEAD')
71+
72+
await checkCommit(head)
73+
console.log('⚙️ Linting using git HEAD (%s)', head)
74+
75+
return ['origin/master', head]
76+
}
77+
78+
const lint = ([from, to]: string[]) =>
79+
execa(
80+
'node',
81+
[require('@commitlint/cli'), '--from', from, '--to', to],
82+
{stdio: 'inherit'}
83+
)
84+
85+
export const run = () =>
86+
getRangeFromPr()
87+
.catch(getRangeFromCompare)
88+
.catch(getRangeFromSha)
89+
.catch(getRangeFromGit)
90+
.then(lint)

tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es3",
4+
"outDir": "build",
5+
"esModuleInterop": true,
6+
"sourceMap": true,
7+
"declaration": true,
8+
"strict": true,
9+
"importHelpers": true,
10+
"lib": ["es6"]
11+
},
12+
"include": [
13+
"src/**/*.ts"
14+
]
15+
}

0 commit comments

Comments
 (0)