Compare commits
94 Commits
v1.0.25
...
v1.1.0-nex
Author | SHA1 | Date | |
---|---|---|---|
|
17e7434940 | ||
|
feff4b4d2a | ||
|
91f90aedbe | ||
|
cd1c89b2ef | ||
|
52bf53cb39 | ||
|
a8b657735b | ||
|
7fb87741a2 | ||
|
602befcb54 | ||
|
791de9ab50 | ||
|
3c630ecb73 | ||
|
62cc7b142a | ||
|
49c817ef10 | ||
|
e17f0be682 | ||
|
97c305eeb7 | ||
|
a443da7025 | ||
|
07b2bb76e0 | ||
|
2ad49c269e | ||
|
fd0321acf5 | ||
|
dbd50a89e4 | ||
|
5027ab963e | ||
|
95daa3318c | ||
|
c93b1511f1 | ||
|
0ceab70142 | ||
|
2eb10280a7 | ||
|
e4a2588002 | ||
|
694ba91ecc | ||
|
a683b39f9f | ||
|
8253c064fe | ||
|
7af34fda05 | ||
|
d4dd907bb0 | ||
|
b0c97c8ec6 | ||
|
a0b73020ce | ||
|
04fbe0af6f | ||
|
d4184b0b6b | ||
|
064eb14315 | ||
|
b07cc92b5c | ||
|
e5ba2cf34b | ||
|
f68439999d | ||
|
1da350a3d0 | ||
|
6ffe17f8b4 | ||
|
4aef61f232 | ||
|
5e0ef822fd | ||
|
94635fe447 | ||
|
5b36813618 | ||
|
dcf9898d67 | ||
|
884fc90171 | ||
|
b97833f7c5 | ||
|
1d6848cd17 | ||
|
0e016f41d3 | ||
|
8f9b4ccf8d | ||
|
51da6c20db | ||
|
f7a8341bb1 | ||
|
c361d6e2b6 | ||
|
ef137b518e | ||
|
3e66d85077 | ||
|
16430922c4 | ||
|
20b7de127d | ||
|
9def6961a9 | ||
|
f846c5ee47 | ||
|
8133f1f32e | ||
|
19e564c928 | ||
|
9c0b62271d | ||
|
7ceb9cb783 | ||
|
cee1906a39 | ||
|
0211f01bfb | ||
|
970d603c2e | ||
|
e558e07817 | ||
|
202d6fe6c3 | ||
|
ab02c0d880 | ||
|
110a667b31 | ||
|
fc187df45e | ||
|
389dc4441f | ||
|
bbc8ec9ca5 | ||
|
10151792e7 | ||
|
012928bcda | ||
|
fe15d9358c | ||
|
5753aefaa3 | ||
|
fb228f6b20 | ||
|
903c070e54 | ||
|
58a7dc17bf | ||
|
3ad155575d | ||
|
a5f15dac32 | ||
|
7f42ca053b | ||
|
874894bf33 | ||
|
7440c23ddc | ||
|
226c9425d1 | ||
|
748c821dc3 | ||
|
1bd01f60bd | ||
|
c8058222e5 | ||
|
b8890fc6d7 | ||
|
bf0785847d | ||
|
46172a5274 | ||
|
8bc2714b55 | ||
|
0543c05431 |
21
.eslintrc
21
.eslintrc
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"prettier/@typescript-eslint",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"prefer-rest-params": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off"
|
||||
}
|
||||
}
|
17
.eslintrc.js
Normal file
17
.eslintrc.js
Normal file
@@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parserOptions: {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
},
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:prettier/recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
],
|
||||
};
|
13
.github/CODEOWNERS
vendored
Normal file
13
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Lines starting with '#' are comments.
|
||||
# Each line is a file pattern followed by one or more owners.
|
||||
|
||||
# These owners will be the default owners for everything in the repo.
|
||||
* @simonecorsi
|
||||
|
||||
# Order is important. The last matching pattern has the most precedence.
|
||||
# So if a pull request only touches javascript files, only these owners
|
||||
# will be requested to review.
|
||||
# *.js @octocat @github/js
|
||||
|
||||
# You can also use email addresses if you prefer.
|
||||
# docs/* docs@example.com
|
18
.github/dependabot.yml
vendored
Normal file
18
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: 'npm' # See documentation for possible values
|
||||
directory: '/' # Location of package manifests
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: 'github-actions'
|
||||
directory: '/'
|
||||
schedule:
|
||||
interval: 'daily'
|
||||
open-pull-requests-limit: 10
|
15
.github/pull_request_template.md
vendored
Normal file
15
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
## 🚨 Proposed changes
|
||||
|
||||
> Please review the [guidelines for contributing](../../CONTRIBUTING.md) to this repository.
|
||||
|
||||
[[Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue.]]
|
||||
|
||||
## ⚙️ Types of changes
|
||||
|
||||
What types of changes does your code introduce? _Put an `x` in the boxes that apply_
|
||||
|
||||
- [ ] New feature (non-breaking change which adds functionality)
|
||||
- [ ] Bugfix (non-breaking change which fixes an issue)
|
||||
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- [ ] Documentation Update (if none of the other choices apply)
|
||||
- [ ] Refactor
|
21
.github/workflows/merge.yml
vendored
Normal file
21
.github/workflows/merge.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Run tests
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node-version: [16.x]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm it
|
44
.github/workflows/release.yaml
vendored
44
.github/workflows/release.yaml
vendored
@@ -1,44 +0,0 @@
|
||||
name: Publish workflow
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: main
|
||||
|
||||
jobs:
|
||||
version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: fregante/setup-git-user@v1
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}
|
||||
|
||||
- name: build
|
||||
run: npm ci && npm run build
|
||||
|
||||
- name: Bump version and push tag
|
||||
id: changelog
|
||||
uses: TriPSs/conventional-changelog-action@v2
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
git-message: 'chore(release): {version}'
|
||||
preset: ''
|
||||
|
||||
- name: Create github Release
|
||||
uses: actions/create-release@v1
|
||||
if: ${{ steps.changelog.outputs.skipped == 'false' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.changelog.outputs.tag }}
|
||||
release_name: ${{ steps.changelog.outputs.tag }}
|
||||
body: ${{ steps.changelog.outputs.changelog }}
|
||||
|
||||
- name: Latest tag
|
||||
uses: EndBug/latest-tag@v1.4.0
|
46
.github/workflows/release.yml
vendored
Normal file
46
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Release
|
||||
|
||||
on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node-version: [16.x]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm it
|
||||
|
||||
release:
|
||||
needs: [test]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm i
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Semantic release
|
||||
uses: codfish/semantic-release-action@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GIT_AUTHOR_NAME: '${{ github.actor }}'
|
||||
GIT_COMMITTER_NAME: '${{ github.actor }}'
|
1
.husky/.gitignore
vendored
Normal file
1
.husky/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
_
|
4
.husky/commit-msg
Executable file
4
.husky/commit-msg
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install commitlint --edit $1
|
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install lint-staged
|
@@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
hooks: {
|
||||
'prepare-commit-msg': 'exec < /dev/tty && git cz --hook || true',
|
||||
'pre-commit': 'lint-staged',
|
||||
'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
|
||||
},
|
||||
};
|
25
.releaserc.json
Normal file
25
.releaserc.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"branches": [
|
||||
{ "name": "main" },
|
||||
{ "name": "next", "channel": "next", "prerelease": true }
|
||||
],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/changelog",
|
||||
[
|
||||
"@semantic-release/git",
|
||||
{
|
||||
"assets": ["CHANGELOG.md", "package.json", "package-lock.json"]
|
||||
}
|
||||
],
|
||||
"@semantic-release/github",
|
||||
[
|
||||
"@saithodev/semantic-release-backmerge",
|
||||
{
|
||||
"branches": [{ "from": "main", "to": "next" }],
|
||||
"backmergeStrategy": "rebase"
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
105
CHANGELOG.md
105
CHANGELOG.md
@@ -1,82 +1,43 @@
|
||||
## <small>1.0.25 (2021-01-16)</small>
|
||||
|
||||
* fix: should fix unshallow repo ([17c5d85](https://github.com/simonecorsi/mawesome/commit/17c5d85))
|
||||
# [1.1.0-next.2](https://github.com/simonecorsi/mawesome/compare/v1.1.0-next.1...v1.1.0-next.2) (2022-05-09)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
## <small>1.0.24 (2021-01-16)</small>
|
||||
* using gh-star-fetch ([a8b6577](https://github.com/simonecorsi/mawesome/commit/a8b657735b9879636cc039d79fddcdca33ccf38e))
|
||||
|
||||
* chore(release): v1.0.22 ([3f66738](https://github.com/simonecorsi/mawesome/commit/3f66738))
|
||||
* chore(release): v1.0.23 ([f41befa](https://github.com/simonecorsi/mawesome/commit/f41befa))
|
||||
* chore(release): v1.0.24 ([9badeaf](https://github.com/simonecorsi/mawesome/commit/9badeaf))
|
||||
* fix: git pull strategy ([edb4a38](https://github.com/simonecorsi/mawesome/commit/edb4a38))
|
||||
* fix: git push ([c8fb3f4](https://github.com/simonecorsi/mawesome/commit/c8fb3f4))
|
||||
* docs: added authors ([3de0e12](https://github.com/simonecorsi/mawesome/commit/3de0e12))
|
||||
# [1.1.0-next.1](https://github.com/simonecorsi/mawesome/compare/v1.0.45...v1.1.0-next.1) (2022-04-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
## <small>1.0.21 (2021-01-16)</small>
|
||||
|
||||
* chore: action name ([8f3ce98](https://github.com/simonecorsi/mawesome/commit/8f3ce98))
|
||||
* chore: moved helpers in own file ([29bcf41](https://github.com/simonecorsi/mawesome/commit/29bcf41))
|
||||
* chore: namings ([b16fdb0](https://github.com/simonecorsi/mawesome/commit/b16fdb0))
|
||||
* chore: post release script ([12dd0e4](https://github.com/simonecorsi/mawesome/commit/12dd0e4))
|
||||
* chore(action.yml): node downgrated to 12 ([f91b26b](https://github.com/simonecorsi/mawesome/commit/f91b26b))
|
||||
* chore(action.yml): updated ([7bdae48](https://github.com/simonecorsi/mawesome/commit/7bdae48))
|
||||
* chore(release): 1.0.1 ([4193d0e](https://github.com/simonecorsi/mawesome/commit/4193d0e))
|
||||
* chore(release): 1.0.2 ([00b27bf](https://github.com/simonecorsi/mawesome/commit/00b27bf))
|
||||
* chore(release): 1.0.3 ([bb5dd1f](https://github.com/simonecorsi/mawesome/commit/bb5dd1f))
|
||||
* chore(release): 1.0.4 ([be86777](https://github.com/simonecorsi/mawesome/commit/be86777))
|
||||
* chore(release): 1.0.5 ([a47a53f](https://github.com/simonecorsi/mawesome/commit/a47a53f))
|
||||
* chore(release): v1.0.1 ([e297342](https://github.com/simonecorsi/mawesome/commit/e297342))
|
||||
* chore(release): v1.0.10 ([c2a11da](https://github.com/simonecorsi/mawesome/commit/c2a11da))
|
||||
* chore(release): v1.0.11 ([ab4322e](https://github.com/simonecorsi/mawesome/commit/ab4322e))
|
||||
* chore(release): v1.0.12 ([0be94f1](https://github.com/simonecorsi/mawesome/commit/0be94f1))
|
||||
* chore(release): v1.0.13 ([ee21996](https://github.com/simonecorsi/mawesome/commit/ee21996))
|
||||
* chore(release): v1.0.14 ([91de25f](https://github.com/simonecorsi/mawesome/commit/91de25f))
|
||||
* chore(release): v1.0.15 ([03e1973](https://github.com/simonecorsi/mawesome/commit/03e1973))
|
||||
* chore(release): v1.0.16 ([f8cb892](https://github.com/simonecorsi/mawesome/commit/f8cb892))
|
||||
* chore(release): v1.0.17 ([380a0ec](https://github.com/simonecorsi/mawesome/commit/380a0ec))
|
||||
* chore(release): v1.0.18 ([d82b715](https://github.com/simonecorsi/mawesome/commit/d82b715))
|
||||
* chore(release): v1.0.19 ([7a46627](https://github.com/simonecorsi/mawesome/commit/7a46627))
|
||||
* chore(release): v1.0.2 ([3cba062](https://github.com/simonecorsi/mawesome/commit/3cba062))
|
||||
* chore(release): v1.0.20 ([738785e](https://github.com/simonecorsi/mawesome/commit/738785e))
|
||||
* chore(release): v1.0.21 ([3c3ab0a](https://github.com/simonecorsi/mawesome/commit/3c3ab0a))
|
||||
* chore(release): v1.0.3 ([71625bd](https://github.com/simonecorsi/mawesome/commit/71625bd))
|
||||
* chore(release): v1.0.4 ([46583c7](https://github.com/simonecorsi/mawesome/commit/46583c7))
|
||||
* chore(release): v1.0.5 ([ba24bdf](https://github.com/simonecorsi/mawesome/commit/ba24bdf))
|
||||
* chore(release): v1.0.6 ([6cb192b](https://github.com/simonecorsi/mawesome/commit/6cb192b))
|
||||
* chore(release): v1.0.7 ([410e2a7](https://github.com/simonecorsi/mawesome/commit/410e2a7))
|
||||
* chore(release): v1.0.8 ([324332b](https://github.com/simonecorsi/mawesome/commit/324332b))
|
||||
* chore(release): v1.0.9 ([7499f86](https://github.com/simonecorsi/mawesome/commit/7499f86))
|
||||
* fix: added latest tag at release ([6b8b525](https://github.com/simonecorsi/mawesome/commit/6b8b525))
|
||||
* fix: added missing info for action publishing ([3703b66](https://github.com/simonecorsi/mawesome/commit/3703b66))
|
||||
* fix: added required label ([173ce50](https://github.com/simonecorsi/mawesome/commit/173ce50))
|
||||
* fix: bad quotes in url ([76d0173](https://github.com/simonecorsi/mawesome/commit/76d0173))
|
||||
* fix: better errors ([f302126](https://github.com/simonecorsi/mawesome/commit/f302126))
|
||||
* fix: better template management ([9d06abc](https://github.com/simonecorsi/mawesome/commit/9d06abc))
|
||||
* fix: exit condition ([914a115](https://github.com/simonecorsi/mawesome/commit/914a115))
|
||||
* fix: if tempalte fail should exit(1) ([ee824d1](https://github.com/simonecorsi/mawesome/commit/ee824d1))
|
||||
* fix: imports ([2e421f0](https://github.com/simonecorsi/mawesome/commit/2e421f0))
|
||||
* fix: imports ([376451a](https://github.com/simonecorsi/mawesome/commit/376451a))
|
||||
* fix: somehow runner wont see template ([808c35c](https://github.com/simonecorsi/mawesome/commit/808c35c))
|
||||
* fix: splitting tokens ([bd47078](https://github.com/simonecorsi/mawesome/commit/bd47078))
|
||||
* fix: template cannot be loaded from ejs file ([78c0f37](https://github.com/simonecorsi/mawesome/commit/78c0f37))
|
||||
* fix: variable name ([13e1fd1](https://github.com/simonecorsi/mawesome/commit/13e1fd1))
|
||||
* fix(action.yml): output file now correct path ([98b17f8](https://github.com/simonecorsi/mawesome/commit/98b17f8))
|
||||
* fix(ci): bad syntax ([caaf6ab](https://github.com/simonecorsi/mawesome/commit/caaf6ab))
|
||||
* fix(index.ts): fs promise fixed path ([285e193](https://github.com/simonecorsi/mawesome/commit/285e193))
|
||||
* docs: added readme ([e1c9ca0](https://github.com/simonecorsi/mawesome/commit/e1c9ca0))
|
||||
* docs: readme updated ([192aa8a](https://github.com/simonecorsi/mawesome/commit/192aa8a))
|
||||
* feat: better errors ([1700aa3](https://github.com/simonecorsi/mawesome/commit/1700aa3))
|
||||
* feat: generate awesome list from stars ([0f6fa76](https://github.com/simonecorsi/mawesome/commit/0f6fa76))
|
||||
* feat: git user now is action ([aa70ac9](https://github.com/simonecorsi/mawesome/commit/aa70ac9))
|
||||
* ci: added github user setup ([a4bbd4b](https://github.com/simonecorsi/mawesome/commit/a4bbd4b))
|
||||
* ci: better release ([ea34727](https://github.com/simonecorsi/mawesome/commit/ea34727))
|
||||
* ci(version): prefixed now with v ([f3d2757](https://github.com/simonecorsi/mawesome/commit/f3d2757))
|
||||
* build: better releasing workflow ([ac6e274](https://github.com/simonecorsi/mawesome/commit/ac6e274))
|
||||
* build(index.js): build ([e007c3b](https://github.com/simonecorsi/mawesome/commit/e007c3b))
|
||||
* Initial commit ([e884018](https://github.com/simonecorsi/mawesome/commit/e884018))
|
||||
* pre-tags ([602befc](https://github.com/simonecorsi/mawesome/commit/602befcb5494b5bfd74d2333899311b81ea9da6d))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **template:** adds templates ([791de9a](https://github.com/simonecorsi/mawesome/commit/791de9ab504de50e2e9cb031b9e373d7cc0589c0)), closes [#14](https://github.com/simonecorsi/mawesome/issues/14)
|
||||
|
||||
## <small>1.0.45 (2022-01-17)</small>
|
||||
|
||||
- build(deps): bump shelljs from 0.8.4 to 0.8.5 ([1da350a](https://github.com/simonecorsi/mawesome/commit/1da350a))
|
||||
|
||||
## <small>1.0.44 (2021-10-26)</small>
|
||||
|
||||
- chore(release): v1.0.44 ([6ffe17f](https://github.com/simonecorsi/mawesome/commit/6ffe17f))
|
||||
- feat: git add multiple files at once ([4aef61f](https://github.com/simonecorsi/mawesome/commit/4aef61f))
|
||||
|
||||
## <small>1.0.43 (2021-10-15)</small>
|
||||
|
||||
- chore(release): v1.0.43 ([5e0ef82](https://github.com/simonecorsi/mawesome/commit/5e0ef82))
|
||||
- feat: reduce json output size ([94635fe](https://github.com/simonecorsi/mawesome/commit/94635fe))
|
||||
|
||||
## <small>1.0.42 (2021-10-14)</small>
|
||||
|
||||
- chore(release): v1.0.42 ([5b36813](https://github.com/simonecorsi/mawesome/commit/5b36813))
|
||||
- fix(paginator): last page now correctly matches rex ([dcf9898](https://github.com/simonecorsi/mawesome/commit/dcf9898))
|
||||
|
||||
## <small>1.0.41 (2021-10-14)</small>
|
||||
|
||||
- chore(release): v1.0.41 ([884fc90](https://github.com/simonecorsi/mawesome/commit/884fc90))
|
||||
- test: fixs suite ([b97833f](https://github.com/simonecorsi/mawesome/commit/b97833f))
|
||||
- fix: should avoid index lock ([1d6848c](https://github.com/simonecorsi/mawesome/commit/1d6848c))
|
||||
|
44
README.md
44
README.md
@@ -1,24 +1,45 @@
|
||||
# My Awesome list
|
||||
# My Awesome List
|
||||
|
||||
This action query the github api to get starred list of the user and then generates a list ordered by languages.
|
||||
This action query the github api to get starred list of the user and then generates a list ordered by languages.
|
||||
|
||||
You can see an example of the output at my own [simonecorsi/awesome](https://github.com/simonecorsi/awesome)
|
||||
|
||||
## Setup
|
||||
## Table of Contents
|
||||
|
||||
To use this action you have to create your own repository (eg: `yourname/awesome`), then create a new empty action in it and then use the [example workflow](#example-workflow) below as a starting point.
|
||||
<!-- toc -->
|
||||
|
||||
## Inputs
|
||||
- [Table of Contents](#table-of-contents)
|
||||
- [Documentation](#documentation)
|
||||
- [Requirements](#requirements)
|
||||
- [Configuration](#configuration)
|
||||
- [`api-token`](#api-token)
|
||||
- [Example workflow](#example-workflow)
|
||||
|
||||
### `github-token`
|
||||
<!-- tocstop -->
|
||||
|
||||
The github workflow token is mandatory
|
||||
## Documentation
|
||||
|
||||
### `api-token`
|
||||
### Requirements
|
||||
|
||||
- An empty repository
|
||||
- A personal github api key
|
||||
|
||||
### Configuration
|
||||
|
||||
The service can be configured setting the appropriate environment variables or writing an `.env` file.
|
||||
|
||||
| Variable | Description | Default |
|
||||
| -------------- | ------------------------------------------- | -------------------------------- |
|
||||
| `api-token` | Personal github api token. | `${{ secrets.API_TOKEN }}` |
|
||||
| `github-token` | Action Token | `${{ secrets.GITHUB_TOKEN }}` |
|
||||
| `github-name` | Name used for the commit, default to action | Github Action |
|
||||
| `github-email` | email used for commit, default to action | actions@users.noreply.github.com |
|
||||
|
||||
#### `api-token`
|
||||
|
||||
The Personal API Access Token is mandatory to fetch stars from the API without incurring in Rate Limits.
|
||||
|
||||
You'll have to generate a [personal api token][https://github.com/settings/tokens/new] and then add
|
||||
You'll have to generate a [personal api token](https://github.com/settings/tokens/new) and then add
|
||||
|
||||
## Example workflow
|
||||
|
||||
@@ -36,8 +57,11 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Awesome generator
|
||||
uses: simonecorsi/mawesome@lastest
|
||||
uses: simonecorsi/mawesome@latest
|
||||
with:
|
||||
api-token: ${{ secrets.API_TOKEN }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github-email: ${{ secrets.USER_EMAIL }}
|
||||
github-name: ${{ github.repository_owner }}
|
||||
|
||||
```
|
||||
|
16
action.yml
16
action.yml
@@ -10,6 +10,22 @@ inputs:
|
||||
api-token:
|
||||
description: 'Personal API Token'
|
||||
required: true
|
||||
github-name:
|
||||
description: 'Name shown in the commit'
|
||||
default: 'GitHub Actions'
|
||||
required: false
|
||||
github-email:
|
||||
description: 'Email shown in the commit'
|
||||
default: 'actions@users.noreply.github.com'
|
||||
required: false
|
||||
template-path:
|
||||
required: false
|
||||
description: 'EJS template path relative to project root directory'
|
||||
default: 'TEMPLATE.ejs'
|
||||
output-filename:
|
||||
description: 'The output file name, default to README.md'
|
||||
required: false
|
||||
default: 'README.md'
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'index.js'
|
||||
|
7
ava.config.js
Normal file
7
ava.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
/* eslint-disable node/no-unsupported-features/es-syntax */
|
||||
|
||||
export default {
|
||||
files: ['!templates/**/*'],
|
||||
extensions: ['ts'],
|
||||
require: ['ts-node/register/transpile-only'],
|
||||
};
|
193
index.js
193
index.js
@@ -18482,7 +18482,7 @@ const testParameter = (name, filters) => {
|
||||
};
|
||||
|
||||
const normalizeDataURL = (urlString, {stripHash}) => {
|
||||
const parts = urlString.match(/^data:(.*?),(.*?)(?:#(.*))?$/);
|
||||
const parts = urlString.match(/^data:([^,]*?),([^#]*?)(?:#(.*))?$/);
|
||||
|
||||
if (!parts) {
|
||||
throw new Error(`Invalid URL: ${urlString}`);
|
||||
@@ -20801,6 +20801,7 @@ function factory(key, options) {
|
||||
* https://github.com/jhermsmeier/node-http-link-header
|
||||
*/
|
||||
|
||||
/* istanbul ignore file */
|
||||
|
||||
|
||||
var COMPATIBLE_ENCODING_PATTERN = /^utf-?8|ascii|utf-?16-?le|ucs-?2|base-?64|latin-?1$/i;
|
||||
@@ -21263,7 +21264,7 @@ const core = __importStar(__nccwpck_require__(2186));
|
||||
const exec = __importStar(__nccwpck_require__(1514));
|
||||
const { GITHUB_REPOSITORY, GITHUB_REF } = process.env;
|
||||
const branch = GITHUB_REF === null || GITHUB_REF === void 0 ? void 0 : GITHUB_REF.replace('refs/heads/', '');
|
||||
exports.default = new (class Git {
|
||||
class Git {
|
||||
constructor() {
|
||||
this.isShallow = () => __awaiter(this, void 0, void 0, function* () {
|
||||
const isShallow = yield this.exec('rev-parse --is-shallow-repository');
|
||||
@@ -21290,7 +21291,16 @@ exports.default = new (class Git {
|
||||
}));
|
||||
};
|
||||
this.config = (prop, value) => this.exec(`config ${prop} "${value}"`);
|
||||
this.add = (file) => this.exec(`add ${file}`);
|
||||
this.add = (file) => {
|
||||
let str = '';
|
||||
if (Array.isArray(file)) {
|
||||
file.map((f) => (str += ` ${f}`));
|
||||
}
|
||||
else {
|
||||
str = file;
|
||||
}
|
||||
return this.exec(`add ${str}`);
|
||||
};
|
||||
this.commit = (message) => this.exec(`commit -m "${message}"`);
|
||||
this.pull = () => __awaiter(this, void 0, void 0, function* () {
|
||||
const args = ['pull'];
|
||||
@@ -21307,14 +21317,17 @@ exports.default = new (class Git {
|
||||
this.createTag = (tag) => this.exec(`tag -a ${tag} -m "${tag}"`);
|
||||
const githubToken = core.getInput('github-token', { required: true });
|
||||
core.setSecret(githubToken);
|
||||
const githubName = core.getInput('github-name') || 'GitHub Actions';
|
||||
const githubEmail = core.getInput('github-email') || 'actions@users.noreply.github.com';
|
||||
// Set config
|
||||
this.config('user.name', 'GitHub Actions');
|
||||
this.config('user.email', 'actions@users.noreply.github.com');
|
||||
this.config('user.name', githubName);
|
||||
this.config('user.email', githubEmail);
|
||||
this.config('pull.rebase', 'false');
|
||||
// Update the origin
|
||||
this.updateOrigin(`https://x-access-token:${githubToken}@github.com/${GITHUB_REPOSITORY}.git`);
|
||||
}
|
||||
})();
|
||||
}
|
||||
exports.default = new Git();
|
||||
|
||||
|
||||
/***/ }),
|
||||
@@ -21352,12 +21365,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
||||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
|
||||
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
|
||||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
||||
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
||||
function fulfill(value) { resume("next", value); }
|
||||
function reject(value) { resume("throw", value); }
|
||||
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
||||
};
|
||||
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var m = o[Symbol.asyncIterator], i;
|
||||
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
||||
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
||||
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.pushNewFile = exports.OUTPUT_FILENAME = exports.generateMd = exports.paginate = exports.API_STARRED_URL = exports.REPO_USERNAME = exports.apiGetStar = exports.renderer = exports.isLastPage = exports.wait = void 0;
|
||||
exports.pushNewFiles = exports.MARKDOWN_FILENAME = exports.generateMd = exports.apiGetStar = exports.getNextPage = exports.renderer = exports.wait = exports.API_STARRED_URL = exports.REPO_USERNAME = void 0;
|
||||
const fs_1 = __importDefault(__nccwpck_require__(5747));
|
||||
const ejs_1 = __importDefault(__nccwpck_require__(8431));
|
||||
const core = __importStar(__nccwpck_require__(2186));
|
||||
const remark_1 = __importDefault(__nccwpck_require__(2081));
|
||||
@@ -21366,16 +21399,13 @@ const template_1 = __importDefault(__nccwpck_require__(3932));
|
||||
const api_1 = __importDefault(__nccwpck_require__(8229));
|
||||
const link_1 = __importDefault(__nccwpck_require__(9338));
|
||||
const git_1 = __importDefault(__nccwpck_require__(6350));
|
||||
const fs_1 = __importDefault(__nccwpck_require__(5747));
|
||||
exports.REPO_USERNAME = (_a = process.env.GITHUB_REPOSITORY) === null || _a === void 0 ? void 0 : _a.split('/')[0];
|
||||
exports.API_STARRED_URL = `${process.env.GITHUB_API_URL}/users/${exports.REPO_USERNAME}/starred`;
|
||||
const fsp = fs_1.default.promises;
|
||||
function wait(time = 200) {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
exports.wait = wait;
|
||||
function isLastPage(links) {
|
||||
return links.next === links.last;
|
||||
}
|
||||
exports.isLastPage = isLastPage;
|
||||
function renderer(data, templateString = template_1.default) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
@@ -21388,32 +21418,91 @@ function renderer(data, templateString = template_1.default) {
|
||||
});
|
||||
}
|
||||
exports.renderer = renderer;
|
||||
function apiGetStar(url) {
|
||||
function getNextPage(links) {
|
||||
const next = links.find((l) => l.rel === 'next');
|
||||
const last = links.find((l) => l.rel === 'last');
|
||||
if (!next || !last)
|
||||
return null;
|
||||
const matchNext = next.uri.match(/page=([0-9]*)/);
|
||||
const matchLast = last.uri.match(/page=([0-9]*)/);
|
||||
if (!matchNext || !matchLast)
|
||||
return null;
|
||||
if (matchNext[1] === matchLast[1])
|
||||
return null;
|
||||
return matchNext[1];
|
||||
}
|
||||
exports.getNextPage = getNextPage;
|
||||
function paginateStars(url) {
|
||||
return __asyncGenerator(this, arguments, function* paginateStars_1() {
|
||||
let nextPage = '1';
|
||||
while (nextPage) {
|
||||
try {
|
||||
const { headers, body } = yield __await(api_1.default.get(url, {
|
||||
searchParams: {
|
||||
page: nextPage,
|
||||
},
|
||||
}));
|
||||
yield yield __await(body);
|
||||
nextPage = getNextPage(link_1.default.parse(headers.link).refs);
|
||||
yield __await(wait(1000)); // avoid limits
|
||||
}
|
||||
catch (e) {
|
||||
console.error(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function apiGetStar(url = exports.API_STARRED_URL) {
|
||||
var e_1, _a;
|
||||
var _b, _c, _d, _e, _f;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const { headers, body } = yield api_1.default.get(url);
|
||||
return {
|
||||
data: body,
|
||||
links: link_1.default.parse(headers.link).refs.reduce((acc, val) => (Object.assign(Object.assign({}, acc), { [val.rel]: val.uri })), {}),
|
||||
};
|
||||
const data = [];
|
||||
try {
|
||||
for (var _g = __asyncValues(paginateStars(url)), _h; _h = yield _g.next(), !_h.done;) {
|
||||
const stars = _h.value;
|
||||
for (const star of stars) {
|
||||
data.push({
|
||||
id: star.id,
|
||||
node_id: star.node_id,
|
||||
name: star.name,
|
||||
full_name: star.full_name,
|
||||
owner: {
|
||||
login: (_b = star === null || star === void 0 ? void 0 : star.owner) === null || _b === void 0 ? void 0 : _b.login,
|
||||
id: (_c = star === null || star === void 0 ? void 0 : star.owner) === null || _c === void 0 ? void 0 : _c.id,
|
||||
avatar_url: (_d = star === null || star === void 0 ? void 0 : star.owner) === null || _d === void 0 ? void 0 : _d.avatar_url,
|
||||
url: (_e = star === null || star === void 0 ? void 0 : star.owner) === null || _e === void 0 ? void 0 : _e.url,
|
||||
html_url: (_f = star === null || star === void 0 ? void 0 : star.owner) === null || _f === void 0 ? void 0 : _f.html_url,
|
||||
},
|
||||
html_url: star.html_url,
|
||||
description: star.description,
|
||||
url: star.url,
|
||||
languages_url: star.languages_url,
|
||||
created_at: star.created_at,
|
||||
updated_at: star.updated_at,
|
||||
git_url: star.git_url,
|
||||
ssh_url: star.ssh_url,
|
||||
clone_url: star.clone_url,
|
||||
homepage: star.homepage,
|
||||
stargazers_count: star.stargazers_count,
|
||||
watchers_count: star.watchers_count,
|
||||
language: star.language,
|
||||
topics: star.topics,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (_h && !_h.done && (_a = _g.return)) yield _a.call(_g);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
}
|
||||
return data;
|
||||
});
|
||||
}
|
||||
exports.apiGetStar = apiGetStar;
|
||||
exports.REPO_USERNAME = (_a = process.env.GITHUB_REPOSITORY) === null || _a === void 0 ? void 0 : _a.split('/')[0];
|
||||
exports.API_STARRED_URL = `${process.env.GITHUB_API_URL}/users/${exports.REPO_USERNAME}/starred`;
|
||||
let links = {
|
||||
next: exports.API_STARRED_URL,
|
||||
last: undefined,
|
||||
};
|
||||
function paginate() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (isLastPage(links))
|
||||
return null;
|
||||
const r = yield apiGetStar(links.next);
|
||||
links = r.links;
|
||||
return r;
|
||||
});
|
||||
}
|
||||
exports.paginate = paginate;
|
||||
function generateMd(data) {
|
||||
return new Promise((resolve) => {
|
||||
remark_1.default()
|
||||
@@ -21429,17 +21518,19 @@ function generateMd(data) {
|
||||
});
|
||||
}
|
||||
exports.generateMd = generateMd;
|
||||
exports.OUTPUT_FILENAME = core.getInput('output-filename') || 'README.md';
|
||||
function pushNewFile(markdown) {
|
||||
exports.MARKDOWN_FILENAME = core.getInput('output-filename') || 'README.md';
|
||||
function pushNewFiles(files = []) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
yield fsp.writeFile(exports.OUTPUT_FILENAME, markdown);
|
||||
if (!files.length)
|
||||
return;
|
||||
yield git_1.default.pull();
|
||||
yield git_1.default.add(exports.OUTPUT_FILENAME);
|
||||
yield git_1.default.commit(`chore(${exports.OUTPUT_FILENAME}): updated ${exports.OUTPUT_FILENAME}`);
|
||||
yield Promise.all(files.map(({ filename, data }) => fsp.writeFile(filename, data)));
|
||||
yield git_1.default.add(files.map(({ filename }) => filename));
|
||||
yield git_1.default.commit(`chore(updates): updated entries in files`);
|
||||
yield git_1.default.push();
|
||||
});
|
||||
}
|
||||
exports.pushNewFile = pushNewFile;
|
||||
exports.pushNewFiles = pushNewFiles;
|
||||
|
||||
|
||||
/***/ }),
|
||||
@@ -21483,14 +21574,7 @@ const core = __importStar(__nccwpck_require__(2186));
|
||||
const helpers_1 = __nccwpck_require__(3015);
|
||||
function main() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let results = [];
|
||||
while (true) {
|
||||
// sorry.
|
||||
const r = yield helpers_1.paginate();
|
||||
if (!r || r === null)
|
||||
break;
|
||||
results = results.concat(r.data);
|
||||
}
|
||||
const results = yield helpers_1.apiGetStar();
|
||||
const sortedByLanguages = results.reduce((acc, val) => {
|
||||
const language = val.language || 'generic';
|
||||
if (!acc[language]) {
|
||||
@@ -21507,7 +21591,16 @@ function main() {
|
||||
updatedAt: Date.now(),
|
||||
});
|
||||
const markdown = yield helpers_1.generateMd(rendered);
|
||||
yield helpers_1.pushNewFile(markdown);
|
||||
yield helpers_1.pushNewFiles([
|
||||
{
|
||||
filename: helpers_1.MARKDOWN_FILENAME,
|
||||
data: markdown,
|
||||
},
|
||||
{
|
||||
filename: 'data.json',
|
||||
data: JSON.stringify(sortedByLanguages, null, 2),
|
||||
},
|
||||
]);
|
||||
});
|
||||
}
|
||||
exports.main = main;
|
||||
@@ -21540,6 +21633,8 @@ run();
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.default = `# <%= username %> Awesome List [](https://github.com/sindresorhus/awesome)
|
||||
|
||||
> :star: generated with [simonecorsi/mawesome](https://github.com/simonecorsi/mawesome)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<% for(let [language, repositories] of stars) { %>
|
||||
|
20346
package-lock.json
generated
20346
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
52
package.json
52
package.json
@@ -1,17 +1,19 @@
|
||||
{
|
||||
"name": "mawesome",
|
||||
"version": "1.0.25",
|
||||
"version": "1.1.0-next.1",
|
||||
"description": "Generate awesome list from user starred repositories",
|
||||
"main": "index.js",
|
||||
"author": "Simone Corsi<simonecorsi.dev@gmail.com>",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"test": "nyc --reporter=lcov --reporter=text-summary ava -s -v",
|
||||
"test:watch": "ava -w",
|
||||
"style:lint": "eslint src --ext .ts",
|
||||
"style:prettier": "prettier \"src/**/*.ts\" --list-different --write",
|
||||
"build": "./node_modules/.bin/ncc build src/index.ts -o ./",
|
||||
"dev": "ts-node-dev src/index.ts",
|
||||
"prerelease": "npm run build && "
|
||||
"prerelease": "npm run build",
|
||||
"prepare": "node prepare.js || echo 'Skipping prepare'"
|
||||
},
|
||||
"keywords": [
|
||||
"github",
|
||||
@@ -23,44 +25,48 @@
|
||||
"javascript"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^11.0.0",
|
||||
"@commitlint/config-conventional": "^11.0.0",
|
||||
"@octokit/rest": "^18.0.12",
|
||||
"@commitlint/cli": "^16.2.3",
|
||||
"@commitlint/config-conventional": "^16.2.1",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"@octokit/types": "^6.2.1",
|
||||
"@saithodev/semantic-release-backmerge": "^2.1.2",
|
||||
"@semantic-release/changelog": "^6.0.1",
|
||||
"@semantic-release/commit-analyzer": "^9.0.2",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"@semantic-release/github": "^8.0.4",
|
||||
"@semantic-release/release-notes-generator": "^10.0.3",
|
||||
"@types/ejs": "^3.0.5",
|
||||
"@types/got": "^9.6.11",
|
||||
"@types/got": "^9.6.12",
|
||||
"@types/node": "^14.14.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.6.0",
|
||||
"@typescript-eslint/parser": "^4.6.0",
|
||||
"@vercel/ncc": "^0.26.2",
|
||||
"@types/sinon": "^9.0.10",
|
||||
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
||||
"@typescript-eslint/parser": "^5.22.0",
|
||||
"@vercel/ncc": "^0.33.3",
|
||||
"ava": "^3.8.2",
|
||||
"benchmark": "^2.1.4",
|
||||
"conventional-gitlab-releaser": "^4.0.1",
|
||||
"cz-conventional-changelog": "^3.2.0",
|
||||
"eslint": "^7.17.0",
|
||||
"eslint-config-prettier": "^7.1.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"husky": "^4.2.5",
|
||||
"lint-staged": "^10.2.2",
|
||||
"husky": "^7.0.4",
|
||||
"lint-staged": "^12.3.7",
|
||||
"markdown-toc": "^1.2.0",
|
||||
"ninos": "^3.0.0",
|
||||
"nyc": "^15.0.1",
|
||||
"prettier": "^2.0.5",
|
||||
"standard-version": "^9.0.0",
|
||||
"sinon": "^9.2.3",
|
||||
"ts-node-dev": "^1.1.1",
|
||||
"typescript": "^4.1.3"
|
||||
"typescript": "^4.6.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/exec": "^1.0.4",
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/github": "^4.0.0",
|
||||
"ejs": "^3.1.5",
|
||||
"@actions/exec": "^1.1.1",
|
||||
"ejs": "^3.1.6",
|
||||
"gh-star-fetch": "^1.1.0",
|
||||
"got": "^11.8.1",
|
||||
"remark": "^13.0.0",
|
||||
"remark-toc": "^7.0.0"
|
||||
},
|
||||
"volta": {
|
||||
"node": "14.15.4"
|
||||
"node": "16.14.2",
|
||||
"npm": "8.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
prepare.js
Normal file
13
prepare.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
let isCi = false;
|
||||
|
||||
try {
|
||||
isCi = require('is-ci');
|
||||
} catch (_) {
|
||||
isCi = true;
|
||||
}
|
||||
|
||||
if (!isCi) {
|
||||
require('husky').install();
|
||||
}
|
11
src/api.ts
11
src/api.ts
@@ -1,11 +0,0 @@
|
||||
import got from 'got';
|
||||
import * as core from '@actions/core';
|
||||
|
||||
const GITHUB_TOKEN = core.getInput('api-token', { required: true });
|
||||
|
||||
export default got.extend({
|
||||
headers: {
|
||||
Authorization: `token ${GITHUB_TOKEN}`,
|
||||
},
|
||||
responseType: 'json',
|
||||
});
|
59
src/git.ts
59
src/git.ts
@@ -6,15 +6,18 @@ import * as exec from '@actions/exec';
|
||||
const { GITHUB_REPOSITORY, GITHUB_REF } = process.env;
|
||||
|
||||
const branch = GITHUB_REF?.replace('refs/heads/', '');
|
||||
|
||||
export default new (class Git {
|
||||
class Git {
|
||||
constructor() {
|
||||
const githubToken = core.getInput('github-token', { required: true });
|
||||
core.setSecret(githubToken);
|
||||
|
||||
const githubName = core.getInput('github-name') || 'GitHub Actions';
|
||||
const githubEmail =
|
||||
core.getInput('github-email') || 'actions@users.noreply.github.com';
|
||||
|
||||
// Set config
|
||||
this.config('user.name', 'GitHub Actions');
|
||||
this.config('user.email', 'actions@users.noreply.github.com');
|
||||
this.config('user.name', githubName);
|
||||
this.config('user.email', githubEmail);
|
||||
this.config('pull.rebase', 'false');
|
||||
|
||||
// Update the origin
|
||||
@@ -31,33 +34,39 @@ export default new (class Git {
|
||||
return isShallow.trim().replace('\n', '') === 'true';
|
||||
};
|
||||
|
||||
exec = (command: string): Promise<string> => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
let execOutput = '';
|
||||
async exec(command: string): Promise<string> {
|
||||
let execOutput = '';
|
||||
|
||||
const options = {
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
execOutput += data.toString();
|
||||
},
|
||||
const options = {
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
execOutput += data.toString();
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
const exitCode = await exec.exec(`git ${command}`, undefined, options);
|
||||
const exitCode = await exec.exec(`git ${command}`, undefined, options);
|
||||
|
||||
if (exitCode === 0) {
|
||||
return resolve(execOutput);
|
||||
} else {
|
||||
core.error(`Command "git ${command}" exited with code ${exitCode}.`);
|
||||
return reject(`Command "git ${command}" exited with code ${exitCode}.`);
|
||||
}
|
||||
});
|
||||
};
|
||||
if (exitCode === 0) {
|
||||
return execOutput;
|
||||
} else {
|
||||
core.error(`Command "git ${command}" exited with code ${exitCode}.`);
|
||||
throw new Error(`Command "git ${command}" exited with code ${exitCode}.`);
|
||||
}
|
||||
}
|
||||
|
||||
config = (prop: string, value: string) =>
|
||||
this.exec(`config ${prop} "${value}"`);
|
||||
|
||||
add = (file: string) => this.exec(`add ${file}`);
|
||||
add = (file: string | string[]) => {
|
||||
let str = '';
|
||||
if (Array.isArray(file)) {
|
||||
file.map((f) => (str += ` ${f}`));
|
||||
} else {
|
||||
str = file;
|
||||
}
|
||||
return this.exec(`add ${str}`);
|
||||
};
|
||||
|
||||
commit = (message: string) => this.exec(`commit -m "${message}"`);
|
||||
|
||||
@@ -80,4 +89,6 @@ export default new (class Git {
|
||||
updateOrigin = (repo: string) => this.exec(`remote set-url origin ${repo}`);
|
||||
|
||||
createTag = (tag: string) => this.exec(`tag -a ${tag} -m "${tag}"`);
|
||||
})();
|
||||
}
|
||||
|
||||
export default new Git();
|
||||
|
@@ -1,30 +1,20 @@
|
||||
import fs from 'fs';
|
||||
import ejs from 'ejs';
|
||||
import * as core from '@actions/core';
|
||||
import remark from 'remark';
|
||||
import toc from 'remark-toc';
|
||||
|
||||
import MD_TEMPLATE from './template';
|
||||
import GithubApi from './api';
|
||||
import link from './link';
|
||||
import git from './git';
|
||||
|
||||
import type { PaginationLink, ApiGetStarResponse } from './types';
|
||||
import type { PaginationLink, ApiGetStarResponse, Stars, Star } from './types';
|
||||
|
||||
import fs from 'fs';
|
||||
export const REPO_USERNAME = process.env.GITHUB_REPOSITORY?.split('/')[0];
|
||||
export const API_STARRED_URL = `${process.env.GITHUB_API_URL}/users/${REPO_USERNAME}/starred`;
|
||||
|
||||
const fsp = fs.promises;
|
||||
|
||||
export function wait(time = 200): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
export function isLastPage(links: PaginationLink): boolean {
|
||||
return links.next === links.last;
|
||||
}
|
||||
|
||||
export async function renderer(
|
||||
data: { [key: string]: any },
|
||||
templateString = MD_TEMPLATE
|
||||
templateString: string
|
||||
): Promise<string> {
|
||||
try {
|
||||
return ejs.render(templateString, data);
|
||||
@@ -34,34 +24,6 @@ export async function renderer(
|
||||
}
|
||||
}
|
||||
|
||||
export async function apiGetStar(url: string): Promise<ApiGetStarResponse> {
|
||||
const { headers, body }: any = await GithubApi.get(url);
|
||||
return {
|
||||
data: body,
|
||||
links: link.parse(headers.link).refs.reduce(
|
||||
(acc, val) => ({
|
||||
...acc,
|
||||
[val.rel]: val.uri,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
export const REPO_USERNAME = process.env.GITHUB_REPOSITORY?.split('/')[0];
|
||||
export const API_STARRED_URL = `${process.env.GITHUB_API_URL}/users/${REPO_USERNAME}/starred`;
|
||||
|
||||
let links: PaginationLink = {
|
||||
next: API_STARRED_URL,
|
||||
last: undefined,
|
||||
};
|
||||
export async function paginate(): Promise<ApiGetStarResponse | null> {
|
||||
if (isLastPage(links)) return null;
|
||||
const r = await apiGetStar(links.next);
|
||||
links = r.links;
|
||||
return r;
|
||||
}
|
||||
|
||||
export function generateMd(data: string): Promise<string> {
|
||||
return new Promise((resolve) => {
|
||||
remark()
|
||||
@@ -77,12 +39,23 @@ export function generateMd(data: string): Promise<string> {
|
||||
});
|
||||
}
|
||||
|
||||
export const OUTPUT_FILENAME: string =
|
||||
core.getInput('output-filename') || 'README.md';
|
||||
export async function pushNewFile(markdown: string): Promise<any> {
|
||||
await fsp.writeFile(OUTPUT_FILENAME, markdown);
|
||||
export const MARKDOWN_FILENAME: string = core.getInput('output-filename');
|
||||
|
||||
type File = {
|
||||
filename: string;
|
||||
data: string;
|
||||
};
|
||||
|
||||
export async function pushNewFiles(files: File[] = []): Promise<any> {
|
||||
if (!files.length) return;
|
||||
|
||||
await git.pull();
|
||||
await git.add(OUTPUT_FILENAME);
|
||||
await git.commit(`chore(${OUTPUT_FILENAME}): updated ${OUTPUT_FILENAME}`);
|
||||
|
||||
await Promise.all(
|
||||
files.map(({ filename, data }) => fsp.writeFile(filename, data))
|
||||
);
|
||||
|
||||
await git.add(files.map(({ filename }) => filename));
|
||||
await git.commit(`chore(updates): updated entries in files`);
|
||||
await git.push();
|
||||
}
|
||||
|
71
src/index.ts
71
src/index.ts
@@ -1,47 +1,57 @@
|
||||
import * as core from '@actions/core';
|
||||
import { readdir, readFile } from 'fs/promises';
|
||||
import ghStarFetch from 'gh-star-fetch';
|
||||
|
||||
import {
|
||||
renderer,
|
||||
paginate,
|
||||
REPO_USERNAME,
|
||||
generateMd,
|
||||
pushNewFile,
|
||||
pushNewFiles,
|
||||
MARKDOWN_FILENAME,
|
||||
} from './helpers';
|
||||
import MD_TEMPLATE from './template';
|
||||
|
||||
import type { SortedLanguageList, Stars, Star } from './types';
|
||||
export async function main() {
|
||||
// set default template
|
||||
let template = MD_TEMPLATE;
|
||||
|
||||
export async function main(): Promise<any> {
|
||||
let results: Stars = [];
|
||||
|
||||
while (true) {
|
||||
// sorry.
|
||||
const r = await paginate();
|
||||
if (!r || r === null) break;
|
||||
results = results.concat(r.data);
|
||||
// get template if found in the repo
|
||||
const customTemplatePath = core.getInput('template-path');
|
||||
console.log(`check if customTemplatePath: ${customTemplatePath} exists`);
|
||||
try {
|
||||
const dir = await readdir('./');
|
||||
console.log(dir.join('\n'));
|
||||
template = await readFile('TEMPLATE.ejs', 'utf8');
|
||||
} catch {
|
||||
console.log("Couldn't find template file, using default");
|
||||
}
|
||||
|
||||
const sortedByLanguages = results.reduce(
|
||||
(acc: SortedLanguageList, val: Star) => {
|
||||
const language = val.language || 'generic';
|
||||
if (!acc[language]) {
|
||||
acc[language] = [val];
|
||||
} else {
|
||||
acc[language].push(val);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
const rendered = await renderer({
|
||||
username: REPO_USERNAME,
|
||||
stars: Object.entries(sortedByLanguages),
|
||||
updatedAt: Date.now(),
|
||||
const sortedByLanguages = await ghStarFetch({
|
||||
accessToken: core.getInput('api-token', { required: true }),
|
||||
compactByLanguage: true,
|
||||
});
|
||||
|
||||
const rendered = await renderer(
|
||||
{
|
||||
username: REPO_USERNAME,
|
||||
stars: Object.entries(sortedByLanguages),
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
template
|
||||
);
|
||||
|
||||
const markdown: string = await generateMd(rendered);
|
||||
|
||||
await pushNewFile(markdown);
|
||||
await pushNewFiles([
|
||||
{
|
||||
filename: MARKDOWN_FILENAME,
|
||||
data: markdown,
|
||||
},
|
||||
{
|
||||
filename: 'data.json',
|
||||
data: JSON.stringify(sortedByLanguages, null, 2),
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
export async function run(): Promise<any> {
|
||||
@@ -54,8 +64,9 @@ export async function run(): Promise<any> {
|
||||
|
||||
const catchAll = (info: any) => {
|
||||
core.setFailed(`#catchAll: ${info}`);
|
||||
core.error(info);
|
||||
};
|
||||
process.on('unhandledRejection', catchAll);
|
||||
process.on('uncaughtException', catchAll);
|
||||
|
||||
run();
|
||||
run().catch(core.error);
|
||||
|
383
src/link.js
383
src/link.js
@@ -1,383 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2016 Jonas Hermsmeier
|
||||
* https://github.com/jhermsmeier/node-http-link-header
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var COMPATIBLE_ENCODING_PATTERN = /^utf-?8|ascii|utf-?16-?le|ucs-?2|base-?64|latin-?1$/i;
|
||||
var WS_TRIM_PATTERN = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
|
||||
var WS_CHAR_PATTERN = /\s|\uFEFF|\xA0/;
|
||||
var WS_FOLD_PATTERN = /\r?\n[\x20\x09]+/g;
|
||||
var DELIMITER_PATTERN = /[;,"]/;
|
||||
var WS_DELIMITER_PATTERN = /[;,"]|\s/;
|
||||
|
||||
/**
|
||||
* Token character pattern
|
||||
* @type {RegExp}
|
||||
* @see https://tools.ietf.org/html/rfc7230#section-3.2.6
|
||||
*/
|
||||
var TOKEN_PATTERN = /^[!#$%&'*+\-\.^_`|~\da-zA-Z]+$/;
|
||||
|
||||
var STATE = {
|
||||
IDLE: 1 << 0,
|
||||
URI: 1 << 1,
|
||||
ATTR: 1 << 2,
|
||||
};
|
||||
|
||||
function trim(value) {
|
||||
return value.replace(WS_TRIM_PATTERN, '');
|
||||
}
|
||||
|
||||
function hasWhitespace(value) {
|
||||
return WS_CHAR_PATTERN.test(value);
|
||||
}
|
||||
|
||||
function skipWhitespace(value, offset) {
|
||||
while (hasWhitespace(value[offset])) {
|
||||
offset++;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
function needsQuotes(value) {
|
||||
return WS_DELIMITER_PATTERN.test(value) || !TOKEN_PATTERN.test(value);
|
||||
}
|
||||
|
||||
class Link {
|
||||
/**
|
||||
* Link
|
||||
* @constructor
|
||||
* @param {String} [value]
|
||||
* @returns {Link}
|
||||
*/
|
||||
constructor(value) {
|
||||
/** @type {Array} URI references */
|
||||
this.refs = [];
|
||||
|
||||
if (value) {
|
||||
this.parse(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get refs with given relation type
|
||||
* @param {String} value
|
||||
* @returns {Array<Object>}
|
||||
*/
|
||||
rel(value) {
|
||||
var links = [];
|
||||
var type = value.toLowerCase();
|
||||
|
||||
for (var i = 0; i < this.refs.length; i++) {
|
||||
if (this.refs[i].rel.toLowerCase() === type) {
|
||||
links.push(this.refs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get refs where given attribute has a given value
|
||||
* @param {String} attr
|
||||
* @param {String} value
|
||||
* @returns {Array<Object>}
|
||||
*/
|
||||
get(attr, value) {
|
||||
attr = attr.toLowerCase();
|
||||
|
||||
var links = [];
|
||||
|
||||
for (var i = 0; i < this.refs.length; i++) {
|
||||
if (this.refs[i][attr] === value) {
|
||||
links.push(this.refs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return links;
|
||||
}
|
||||
|
||||
set(link) {
|
||||
this.refs.push(link);
|
||||
return this;
|
||||
}
|
||||
|
||||
has(attr, value) {
|
||||
attr = attr.toLowerCase();
|
||||
|
||||
for (var i = 0; i < this.refs.length; i++) {
|
||||
if (this.refs[i][attr] === value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parse(value, offset) {
|
||||
offset = offset || 0;
|
||||
value = offset ? value.slice(offset) : value;
|
||||
|
||||
// Trim & unfold folded lines
|
||||
value = trim(value).replace(WS_FOLD_PATTERN, '');
|
||||
|
||||
var state = STATE.IDLE;
|
||||
var length = value.length;
|
||||
var offset = 0;
|
||||
var ref = null;
|
||||
|
||||
while (offset < length) {
|
||||
if (state === STATE.IDLE) {
|
||||
if (hasWhitespace(value[offset])) {
|
||||
offset++;
|
||||
continue;
|
||||
} else if (value[offset] === '<') {
|
||||
if (ref != null) {
|
||||
ref.rel != null
|
||||
? this.refs.push(...Link.expandRelations(ref))
|
||||
: this.refs.push(ref);
|
||||
}
|
||||
var end = value.indexOf('>', offset);
|
||||
if (end === -1)
|
||||
throw new Error(
|
||||
'Expected end of URI delimiter at offset ' + offset
|
||||
);
|
||||
ref = { uri: value.slice(offset + 1, end) };
|
||||
// this.refs.push( ref )
|
||||
offset = end;
|
||||
state = STATE.URI;
|
||||
} else {
|
||||
throw new Error(
|
||||
'Unexpected character "' + value[offset] + '" at offset ' + offset
|
||||
);
|
||||
}
|
||||
offset++;
|
||||
} else if (state === STATE.URI) {
|
||||
if (hasWhitespace(value[offset])) {
|
||||
offset++;
|
||||
continue;
|
||||
} else if (value[offset] === ';') {
|
||||
state = STATE.ATTR;
|
||||
offset++;
|
||||
} else if (value[offset] === ',') {
|
||||
state = STATE.IDLE;
|
||||
offset++;
|
||||
} else {
|
||||
throw new Error(
|
||||
'Unexpected character "' + value[offset] + '" at offset ' + offset
|
||||
);
|
||||
}
|
||||
} else if (state === STATE.ATTR) {
|
||||
if (value[offset] === ';' || hasWhitespace(value[offset])) {
|
||||
offset++;
|
||||
continue;
|
||||
}
|
||||
var end = value.indexOf('=', offset);
|
||||
if (end === -1)
|
||||
throw new Error('Expected attribute delimiter at offset ' + offset);
|
||||
var attr = trim(value.slice(offset, end)).toLowerCase();
|
||||
var attrValue = '';
|
||||
offset = end + 1;
|
||||
offset = skipWhitespace(value, offset);
|
||||
if (value[offset] === '"') {
|
||||
offset++;
|
||||
while (offset < length) {
|
||||
if (value[offset] === '"') {
|
||||
offset++;
|
||||
break;
|
||||
}
|
||||
if (value[offset] === '\\') {
|
||||
offset++;
|
||||
}
|
||||
attrValue += value[offset];
|
||||
offset++;
|
||||
}
|
||||
} else {
|
||||
var end = offset + 1;
|
||||
while (!DELIMITER_PATTERN.test(value[end]) && end < length) {
|
||||
end++;
|
||||
}
|
||||
attrValue = value.slice(offset, end);
|
||||
offset = end;
|
||||
}
|
||||
if (ref[attr] && Link.isSingleOccurenceAttr(attr)) {
|
||||
// Ignore multiples of attributes which may only appear once
|
||||
} else if (attr[attr.length - 1] === '*') {
|
||||
ref[attr] = Link.parseExtendedValue(attrValue);
|
||||
} else {
|
||||
attrValue = attr === 'type' ? attrValue.toLowerCase() : attrValue;
|
||||
if (ref[attr] != null) {
|
||||
if (Array.isArray(ref[attr])) {
|
||||
ref[attr].push(attrValue);
|
||||
} else {
|
||||
ref[attr] = [ref[attr], attrValue];
|
||||
}
|
||||
} else {
|
||||
ref[attr] = attrValue;
|
||||
}
|
||||
}
|
||||
switch (value[offset]) {
|
||||
case ',':
|
||||
state = STATE.IDLE;
|
||||
break;
|
||||
case ';':
|
||||
state = STATE.ATTR;
|
||||
break;
|
||||
}
|
||||
offset++;
|
||||
} else {
|
||||
throw new Error('Unknown parser state "' + state + '"');
|
||||
}
|
||||
}
|
||||
|
||||
if (ref != null) {
|
||||
ref.rel != null
|
||||
? this.refs.push(...Link.expandRelations(ref))
|
||||
: this.refs.push(ref);
|
||||
}
|
||||
|
||||
ref = null;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
toString() {
|
||||
var refs = [];
|
||||
var link = '';
|
||||
var ref = null;
|
||||
|
||||
for (var i = 0; i < this.refs.length; i++) {
|
||||
ref = this.refs[i];
|
||||
link = Object.keys(this.refs[i]).reduce(function (link, attr) {
|
||||
if (attr === 'uri') return link;
|
||||
return link + '; ' + Link.formatAttribute(attr, ref[attr]);
|
||||
}, '<' + ref.uri + '>');
|
||||
refs.push(link);
|
||||
}
|
||||
|
||||
return refs.join(', ');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether an encoding can be
|
||||
* natively handled with a `Buffer`
|
||||
* @param {String} value
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
Link.isCompatibleEncoding = function (value) {
|
||||
return COMPATIBLE_ENCODING_PATTERN.test(value);
|
||||
};
|
||||
|
||||
Link.parse = function (value, offset) {
|
||||
return new Link().parse(value, offset);
|
||||
};
|
||||
|
||||
Link.isSingleOccurenceAttr = function (attr) {
|
||||
return (
|
||||
attr === 'rel' ||
|
||||
attr === 'type' ||
|
||||
attr === 'media' ||
|
||||
attr === 'title' ||
|
||||
attr === 'title*'
|
||||
);
|
||||
};
|
||||
|
||||
Link.isTokenAttr = function (attr) {
|
||||
return attr === 'rel' || attr === 'type' || attr === 'anchor';
|
||||
};
|
||||
|
||||
Link.escapeQuotes = function (value) {
|
||||
return value.replace(/"/g, '\\"');
|
||||
};
|
||||
|
||||
Link.expandRelations = function (ref) {
|
||||
var rels = ref.rel.split(' ');
|
||||
return rels.map(function (rel) {
|
||||
var value = Object.assign({}, ref);
|
||||
value.rel = rel;
|
||||
return value;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses an extended value and attempts to decode it
|
||||
* @internal
|
||||
* @param {String} value
|
||||
* @return {Object}
|
||||
*/
|
||||
Link.parseExtendedValue = function (value) {
|
||||
var parts = /([^']+)?(?:'([^']+)')?(.+)/.exec(value);
|
||||
return {
|
||||
language: parts[2].toLowerCase(),
|
||||
encoding: Link.isCompatibleEncoding(parts[1])
|
||||
? null
|
||||
: parts[1].toLowerCase(),
|
||||
value: Link.isCompatibleEncoding(parts[1])
|
||||
? decodeURIComponent(parts[3])
|
||||
: parts[3],
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Format a given extended attribute and it's value
|
||||
* @param {String} attr
|
||||
* @param {Object} data
|
||||
* @return {String}
|
||||
*/
|
||||
Link.formatExtendedAttribute = function (attr, data) {
|
||||
var encoding = (data.encoding || 'utf-8').toUpperCase();
|
||||
var language = data.language || 'en';
|
||||
|
||||
var encodedValue = '';
|
||||
|
||||
if (Buffer.isBuffer(data.value) && Link.isCompatibleEncoding(encoding)) {
|
||||
encodedValue = data.value.toString(encoding);
|
||||
} else if (Buffer.isBuffer(data.value)) {
|
||||
encodedValue = data.value.toString('hex').replace(/[0-9a-f]{2}/gi, '%$1');
|
||||
} else {
|
||||
encodedValue = encodeURIComponent(data.value);
|
||||
}
|
||||
|
||||
return attr + '=' + encoding + "'" + language + "'" + encodedValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Format a given attribute and it's value
|
||||
* @param {String} attr
|
||||
* @param {String|Object} value
|
||||
* @return {String}
|
||||
*/
|
||||
Link.formatAttribute = function (attr, value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
.map((item) => {
|
||||
return Link.formatAttribute(attr, item);
|
||||
})
|
||||
.join('; ');
|
||||
}
|
||||
|
||||
if (attr[attr.length - 1] === '*' || typeof value !== 'string') {
|
||||
return Link.formatExtendedAttribute(attr, value);
|
||||
}
|
||||
|
||||
if (Link.isTokenAttr(attr)) {
|
||||
value = needsQuotes(value)
|
||||
? '"' + Link.escapeQuotes(value) + '"'
|
||||
: Link.escapeQuotes(value);
|
||||
} else if (needsQuotes(value)) {
|
||||
value = encodeURIComponent(value);
|
||||
// We don't need to escape <SP> <,> <;> within quotes
|
||||
value = value
|
||||
.replace(/%20/g, ' ')
|
||||
.replace(/%2C/g, ',')
|
||||
.replace(/%3B/g, ';');
|
||||
|
||||
value = '"' + value + '"';
|
||||
}
|
||||
|
||||
return attr + '=' + value;
|
||||
};
|
||||
|
||||
module.exports = Link;
|
@@ -1,5 +1,7 @@
|
||||
export default `# <%= username %> Awesome List [](https://github.com/sindresorhus/awesome)
|
||||
|
||||
> :star: generated with [simonecorsi/mawesome](https://github.com/simonecorsi/mawesome)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
<% for(let [language, repositories] of stars) { %>
|
||||
|
@@ -5,14 +5,11 @@ export type SortedLanguageList = {
|
||||
};
|
||||
|
||||
export type PaginationLink = {
|
||||
next: string;
|
||||
last: string | undefined | null;
|
||||
uri: string;
|
||||
rel: 'next' | 'last' | 'prev' | 'first';
|
||||
};
|
||||
|
||||
export type Stars = Endpoints['GET /user/starred']['response']['data'];
|
||||
export type Star = Stars[number] | { language: string };
|
||||
|
||||
export type ApiGetStarResponse = {
|
||||
links: PaginationLink;
|
||||
data: Stars;
|
||||
};
|
||||
export type ApiGetStarResponse = Stars;
|
||||
|
52
test/helpers.spec.ts
Normal file
52
test/helpers.spec.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import test from 'ava';
|
||||
import * as sinon from 'sinon';
|
||||
import fs from 'fs';
|
||||
|
||||
import * as core from '@actions/core';
|
||||
sinon.replace(core, 'getInput', sinon.fake());
|
||||
|
||||
import Git from '../src/git';
|
||||
const pull = sinon.fake();
|
||||
sinon.replace(Git, 'pull', pull);
|
||||
const add = sinon.fake();
|
||||
sinon.replace(Git, 'add', add);
|
||||
const commit = sinon.fake();
|
||||
sinon.replace(Git, 'commit', commit);
|
||||
const push = sinon.fake();
|
||||
sinon.replace(Git, 'push', push);
|
||||
sinon.replace(Git, 'config', sinon.fake());
|
||||
sinon.replace(Git, 'updateOrigin', sinon.fake());
|
||||
|
||||
const fsp = fs.promises;
|
||||
const writeFile = sinon.fake();
|
||||
sinon.replace(fsp, 'writeFile', writeFile);
|
||||
|
||||
import { renderer, generateMd, pushNewFiles } from '../src/helpers';
|
||||
|
||||
test('renderer should render', async (t) => {
|
||||
const output = await renderer({ variable: 123 }, 'Test: <%= variable %>');
|
||||
t.is(output, 'Test: 123');
|
||||
});
|
||||
|
||||
test('generateMd should create TOC', async (t) => {
|
||||
const tpl = `# title
|
||||
|
||||
## Table of Contents
|
||||
|
||||
## Javascript
|
||||
`;
|
||||
const result = await generateMd(tpl);
|
||||
t.is(
|
||||
result,
|
||||
`# title\n\n## Table of Contents\n\n* [Javascript](#javascript)\n\n## Javascript\n`
|
||||
);
|
||||
});
|
||||
|
||||
test('should push', async (t) => {
|
||||
await pushNewFiles([{ filename: 'README.md', data: '# title' }]);
|
||||
t.true(writeFile.called);
|
||||
t.true(pull.called);
|
||||
t.true(add.called);
|
||||
t.true(commit.called);
|
||||
t.true(push.called);
|
||||
});
|
Reference in New Issue
Block a user