9 Commits

Author SHA1 Message Date
simonecorsi
17e7434940 chore(release): 1.1.0-next.2 [skip ci]
# [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

* using gh-star-fetch ([a8b6577](a8b657735b))
2022-05-09 15:25:56 +00:00
Simone Corsi
feff4b4d2a test: fixed old suites 2022-05-09 17:22:12 +02:00
Simone Corsi
91f90aedbe ci: console 2022-05-09 17:09:32 +02:00
Simone Corsi
cd1c89b2ef ci: moves templates check 2022-05-09 16:50:41 +02:00
Simone Corsi
52bf53cb39 ci: adds logs 2022-05-09 16:49:56 +02:00
Simone Corsi
a8b657735b feat: using gh-star-fetch 2022-05-09 15:57:03 +02:00
simonecorsi
7fb87741a2 chore(release): 1.1.0-next.1 [skip ci]
# [1.1.0-next.1](https://github.com/simonecorsi/mawesome/compare/v1.0.45...v1.1.0-next.1) (2022-04-13)

### Bug Fixes

* pre-tags ([602befc](602befcb54))

### Features

* **template:** adds templates ([791de9a](791de9ab50)), closes [#14](https://github.com/simonecorsi/mawesome/issues/14)
2022-04-13 13:54:00 +00:00
Simone Corsi
602befcb54 fix: pre-tags 2022-04-13 15:51:20 +02:00
Simone Corsi
791de9ab50 feat(template): adds templates
if an `TEMPLATE.ejs` file is found in the repo it will be used for rendering

closes #14
2022-04-13 15:34:08 +02:00
15 changed files with 15790 additions and 20047 deletions

21
.github/workflows/merge.yml vendored Normal file
View 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

View File

@@ -3,7 +3,26 @@ name: Release
on: [workflow_dispatch] on: [workflow_dispatch]
jobs: 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: release:
needs: [test]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/setup-node@v3 - uses: actions/setup-node@v3
@@ -11,8 +30,7 @@ jobs:
node-version: 16 node-version: 16
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
persist-credentials: false
- name: Install dependencies - name: Install dependencies
run: npm i run: npm i
@@ -23,6 +41,6 @@ jobs:
- name: Semantic release - name: Semantic release
uses: codfish/semantic-release-action@v1 uses: codfish/semantic-release-action@v1
env: env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_AUTHOR_NAME: '${{ github.actor }}' GIT_AUTHOR_NAME: '${{ github.actor }}'
GIT_COMMITTER_NAME: '${{ github.actor }}' GIT_COMMITTER_NAME: '${{ github.actor }}'

View File

@@ -10,12 +10,7 @@
[ [
"@semantic-release/git", "@semantic-release/git",
{ {
"assets": [ "assets": ["CHANGELOG.md", "package.json", "package-lock.json"]
"index.js",
"CHANGELOG.md",
"package.json",
"package-lock.json"
]
} }
], ],
"@semantic-release/github", "@semantic-release/github",

View File

@@ -1,42 +1,3 @@
# [2.1.0](https://github.com/simonecorsi/mawesome/compare/v2.0.0...v2.1.0) (2022-05-11)
### Bug Fixes
* removes console.log ([7841262](https://github.com/simonecorsi/mawesome/commit/7841262e741f05debb7ffe6fed636a508a8f7c12))
### Features
* removes github-token need ([0dc2a51](https://github.com/simonecorsi/mawesome/commit/0dc2a51ddf3cf93414afd674ed3c34ec681f3e4b))
# [2.0.0](https://github.com/simonecorsi/mawesome/compare/v1.0.45...v2.0.0) (2022-05-11)
### Bug Fixes
* fixes default template path ([6cd9c30](https://github.com/simonecorsi/mawesome/commit/6cd9c30b20acb0789668b9fd4cdbace2cb52d3ce))
* fixes tsc build ([ec10b79](https://github.com/simonecorsi/mawesome/commit/ec10b79a91bc5894d35b80026d3e216420e0721a))
* normalize template file loadup ([445f562](https://github.com/simonecorsi/mawesome/commit/445f562fb50567d995f0d080d4267fc8d494731b))
* pre-tags ([d1d4edd](https://github.com/simonecorsi/mawesome/commit/d1d4edd104affc69984905c8408e859c25c58443))
* removes unused tests ([a141d23](https://github.com/simonecorsi/mawesome/commit/a141d23972c31b3dbd7e9841168219ad42fa7a18))
* reworking files ([19c4c8f](https://github.com/simonecorsi/mawesome/commit/19c4c8f761b244ddccbc445cc34078bf932559d2))
* updates gh-star-fetch ([3ec4b7c](https://github.com/simonecorsi/mawesome/commit/3ec4b7cd53c1fe885a51fb64279047a201d535dc))
### Features
* release major ([51a4359](https://github.com/simonecorsi/mawesome/commit/51a4359d983be4c842410f0c62104fca1b28252f))
* update to node16 ([e1f37af](https://github.com/simonecorsi/mawesome/commit/e1f37af978ebcb7f770949476ac7d6bc788a1fc2))
* updates deps ([7ade95d](https://github.com/simonecorsi/mawesome/commit/7ade95df8566a59145652165400cddfd1afa4bed))
* using gh-star-fetch ([346ba5d](https://github.com/simonecorsi/mawesome/commit/346ba5d4b7ba6a71bab99f2dbe3c2d010beb67d5))
* **template:** adds templates ([2c742b8](https://github.com/simonecorsi/mawesome/commit/2c742b820558fd715de987178303c460f5871c29)), closes [#14](https://github.com/simonecorsi/mawesome/issues/14)
### BREAKING CHANGES
* refactored code
# [1.1.0-next.2](https://github.com/simonecorsi/mawesome/compare/v1.1.0-next.1...v1.1.0-next.2) (2022-05-09) # [1.1.0-next.2](https://github.com/simonecorsi/mawesome/compare/v1.1.0-next.1...v1.1.0-next.2) (2022-05-09)

View File

@@ -8,11 +8,11 @@ You can see an example of the output at my own [simonecorsi/awesome](https://git
<!-- toc --> <!-- toc -->
- [Table of Contents](#table-of-contents)
- [Documentation](#documentation) - [Documentation](#documentation)
- [Requirements](#requirements) - [Requirements](#requirements)
- [Configuration](#configuration) - [Configuration](#configuration)
- [`api-token`](#api-token) - [`api-token`](#api-token)
- [`template-path`](#template-path)
- [Example workflow](#example-workflow) - [Example workflow](#example-workflow)
<!-- tocstop --> <!-- tocstop -->
@@ -21,39 +21,32 @@ You can see an example of the output at my own [simonecorsi/awesome](https://git
### Requirements ### Requirements
- An empty repository - An empty repository
- A personal github api key - A personal github api key
### Configuration ### Configuration
The service can be configured setting the appropriate environment variables or writing an `.env` file. The service can be configured setting the appropriate environment variables or writing an `.env` file.
| Variable | Description | Default | | Variable | Description | Default |
| ----------------- | ------------------------------------------------------------------- | -------------------------------- | | -------------- | ------------------------------------------- | -------------------------------- |
| `api-token` | Personal Token is used to avoid rate limit, [read more](#api-token) | `${{ secrets.API_TOKEN }}` | | `api-token` | Personal github api token. | `${{ secrets.API_TOKEN }}` |
| `github-name` | Name used for the commit | Github Action | | `github-token` | Action Token | `${{ secrets.GITHUB_TOKEN }}` |
| `github-email` | email used for commit | actions@users.noreply.github.com | | `github-name` | Name used for the commit, default to action | Github Action |
| `template-path` | Custom `README.md` template, [read more](#template-path) | | `github-email` | email used for commit, default to action | actions@users.noreply.github.com |
| `output-filename` | Output filename | `README.md` |
#### `api-token` #### `api-token`
The Personal API Access Token is mandatory to fetch stars from the API without incurring in Rate Limits. 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
#### `template-path`
If you don't like the output (default example [here](./TEMPLATE.ejs) ), you can provide your custom template that will be rendered using [EJS](https://ejs.co/) template engine.
Path provided is relative to your current repository directory, if file is not found it will default.
## Example workflow ## Example workflow
```yml ```yml
name: Update awesome list name: Update awesome list
on: on:
workflow_dispatch: workflow_dispatch:
schedule: schedule:
- cron: '0 0 * * *' - cron: '0 0 * * *'
@@ -70,4 +63,5 @@ jobs:
github-token: ${{ secrets.GITHUB_TOKEN }} github-token: ${{ secrets.GITHUB_TOKEN }}
github-email: ${{ secrets.USER_EMAIL }} github-email: ${{ secrets.USER_EMAIL }}
github-name: ${{ github.repository_owner }} github-name: ${{ github.repository_owner }}
``` ```

View File

@@ -4,6 +4,9 @@ branding:
icon: align-justify icon: align-justify
color: yellow color: yellow
inputs: inputs:
github-token:
description: 'Github token'
required: true
api-token: api-token:
description: 'Personal API Token' description: 'Personal API Token'
required: true required: true
@@ -24,5 +27,5 @@ inputs:
required: false required: false
default: 'README.md' default: 'README.md'
runs: runs:
using: 'node16' using: 'node12'
main: 'index.js' main: 'index.js'

7
ava.config.js Normal file
View 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'],
};

29257
index.js

File diff suppressed because one or more lines are too long

6271
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,18 @@
{ {
"name": "mawesome", "name": "mawesome",
"version": "2.0.0-0", "version": "1.1.0-next.1",
"description": "Generate awesome list from user starred repositories", "description": "Generate awesome list from user starred repositories",
"main": "index.js", "main": "index.js",
"author": "Simone Corsi<simonecorsi.dev@gmail.com>", "author": "Simone Corsi<simonecorsi.dev@gmail.com>",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"test": "nyc --reporter=lcov --reporter=text-summary ava -s -v",
"test:watch": "ava -w",
"style:lint": "eslint src --ext .ts", "style:lint": "eslint src --ext .ts",
"style:prettier": "prettier \"src/**/*.ts\" --list-different --write", "style:prettier": "prettier \"src/**/*.ts\" --list-different --write",
"build": "./node_modules/.bin/ncc build src/index.ts -o ./", "build": "./node_modules/.bin/ncc build src/index.ts -o ./",
"dev": "ts-node-dev src/index.ts", "dev": "ts-node-dev src/index.ts",
"prerelease": "npm run build",
"prepare": "node prepare.js || echo 'Skipping prepare'" "prepare": "node prepare.js || echo 'Skipping prepare'"
}, },
"keywords": [ "keywords": [
@@ -22,8 +25,8 @@
"javascript" "javascript"
], ],
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^16.2.4", "@commitlint/cli": "^16.2.3",
"@commitlint/config-conventional": "^16.2.4", "@commitlint/config-conventional": "^16.2.1",
"@octokit/rest": "^18.12.0", "@octokit/rest": "^18.12.0",
"@octokit/types": "^6.2.1", "@octokit/types": "^6.2.1",
"@saithodev/semantic-release-backmerge": "^2.1.2", "@saithodev/semantic-release-backmerge": "^2.1.2",
@@ -32,34 +35,35 @@
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"@semantic-release/github": "^8.0.4", "@semantic-release/github": "^8.0.4",
"@semantic-release/release-notes-generator": "^10.0.3", "@semantic-release/release-notes-generator": "^10.0.3",
"@types/ejs": "^3.1.0", "@types/ejs": "^3.0.5",
"@types/got": "^9.6.12", "@types/got": "^9.6.12",
"@types/node": "^17.0.32", "@types/node": "^14.14.5",
"@types/sinon": "^10.0.11", "@types/sinon": "^9.0.10",
"@typescript-eslint/eslint-plugin": "^5.23.0", "@typescript-eslint/eslint-plugin": "^5.22.0",
"@typescript-eslint/parser": "^5.23.0", "@typescript-eslint/parser": "^5.22.0",
"@vercel/ncc": "^0.33.4", "@vercel/ncc": "^0.33.3",
"eslint": "^8.15.0", "ava": "^3.8.2",
"eslint-config-prettier": "^8.5.0", "eslint": "^7.17.0",
"eslint-config-prettier": "^7.1.0",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^3.3.1",
"husky": "^8.0.1", "husky": "^7.0.4",
"lint-staged": "^12.4.1", "lint-staged": "^12.3.7",
"markdown-toc": "^1.2.0", "markdown-toc": "^1.2.0",
"nyc": "^15.0.1", "nyc": "^15.0.1",
"prettier": "^2.6.2", "prettier": "^2.0.5",
"sinon": "^14.0.0", "sinon": "^9.2.3",
"ts-node-dev": "^1.1.8", "ts-node-dev": "^1.1.1",
"typescript": "^4.6.4" "typescript": "^4.6.4"
}, },
"dependencies": { "dependencies": {
"@actions/core": "^1.8.0", "@actions/core": "^1.2.6",
"@actions/exec": "^1.1.1", "@actions/exec": "^1.1.1",
"ejs": "^3.1.7", "ejs": "^3.1.6",
"gh-star-fetch": "^1.3.0", "gh-star-fetch": "^1.1.0",
"got": "^11.8.1", "got": "^11.8.1",
"remark": "^14.0.2", "remark": "^13.0.0",
"remark-toc": "^8.0.1" "remark-toc": "^7.0.0"
}, },
"volta": { "volta": {
"node": "16.14.2", "node": "16.14.2",

View File

@@ -2,20 +2,13 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import fs from 'fs/promises';
const { GITHUB_REPOSITORY, GITHUB_REF } = process.env; const { GITHUB_REPOSITORY, GITHUB_REF } = process.env;
const branch = GITHUB_REF?.replace('refs/heads/', ''); const branch = GITHUB_REF?.replace('refs/heads/', '');
type File = {
filename: string;
data: string;
};
class Git { class Git {
constructor() { constructor() {
const githubToken = core.getInput('api-token', { required: true }); const githubToken = core.getInput('github-token', { required: true });
core.setSecret(githubToken); core.setSecret(githubToken);
const githubName = core.getInput('github-name') || 'GitHub Actions'; const githubName = core.getInput('github-name') || 'GitHub Actions';
@@ -96,20 +89,6 @@ class Git {
updateOrigin = (repo: string) => this.exec(`remote set-url origin ${repo}`); updateOrigin = (repo: string) => this.exec(`remote set-url origin ${repo}`);
createTag = (tag: string) => this.exec(`tag -a ${tag} -m "${tag}"`); createTag = (tag: string) => this.exec(`tag -a ${tag} -m "${tag}"`);
async pushNewFiles(files: File[] = []): Promise<any> {
if (!files.length) return;
await this.pull();
await Promise.all(
files.map(({ filename, data }) => fs.writeFile(filename, data))
);
await this.add(files.map(({ filename }) => filename));
await this.commit(`chore(updates): updated entries in files`);
await this.push();
}
} }
export default new Git(); export default new Git();

View File

@@ -1,11 +1,17 @@
import fs from 'fs';
import ejs from 'ejs'; import ejs from 'ejs';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { remark } from 'remark'; import remark from 'remark';
import toc from 'remark-toc'; import toc from 'remark-toc';
import git from './git';
import type { PaginationLink, ApiGetStarResponse, Stars, Star } from './types';
export const REPO_USERNAME = process.env.GITHUB_REPOSITORY?.split('/')[0]; export const REPO_USERNAME = process.env.GITHUB_REPOSITORY?.split('/')[0];
export const API_STARRED_URL = `${process.env.GITHUB_API_URL}/users/${REPO_USERNAME}/starred`; export const API_STARRED_URL = `${process.env.GITHUB_API_URL}/users/${REPO_USERNAME}/starred`;
const fsp = fs.promises;
export async function renderer( export async function renderer(
data: { [key: string]: any }, data: { [key: string]: any },
templateString: string templateString: string
@@ -34,3 +40,22 @@ export function generateMd(data: string): Promise<string> {
} }
export const MARKDOWN_FILENAME: string = core.getInput('output-filename'); 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 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();
}

View File

@@ -1,30 +1,29 @@
import path from 'path';
import * as core from '@actions/core'; import * as core from '@actions/core';
import { readFile } from 'fs/promises'; import { readdir, readFile } from 'fs/promises';
import ghStarFetch from 'gh-star-fetch'; import ghStarFetch from 'gh-star-fetch';
import { import {
renderer, renderer,
REPO_USERNAME, REPO_USERNAME,
generateMd, generateMd,
pushNewFiles,
MARKDOWN_FILENAME, MARKDOWN_FILENAME,
} from './helpers'; } from './helpers';
import git from './git'; import MD_TEMPLATE from './template';
export async function main() { export async function main() {
// set default template // set default template
let template = await readFile( let template = MD_TEMPLATE;
path.resolve(__dirname, './TEMPLATE.ejs'),
'utf8'
);
// get template if found in the repo // get template if found in the repo
const customTemplatePath = core.getInput('template-path'); const customTemplatePath = core.getInput('template-path');
core.info(`check if customTemplatePath: ${customTemplatePath} exists`); console.log(`check if customTemplatePath: ${customTemplatePath} exists`);
try { try {
template = await readFile(customTemplatePath, 'utf8'); const dir = await readdir('./');
console.log(dir.join('\n'));
template = await readFile('TEMPLATE.ejs', 'utf8');
} catch { } catch {
core.info("Couldn't find template file, using default"); console.log("Couldn't find template file, using default");
} }
const sortedByLanguages = await ghStarFetch({ const sortedByLanguages = await ghStarFetch({
@@ -43,7 +42,7 @@ export async function main() {
const markdown: string = await generateMd(rendered); const markdown: string = await generateMd(rendered);
await git.pushNewFiles([ await pushNewFiles([
{ {
filename: MARKDOWN_FILENAME, filename: MARKDOWN_FILENAME,
data: markdown, data: markdown,
@@ -55,7 +54,7 @@ export async function main() {
]); ]);
} }
export async function run(): Promise<void> { export async function run(): Promise<any> {
try { try {
await main(); await main();
} catch (error) { } catch (error) {

View File

@@ -1,4 +1,4 @@
# <%= username %> Awesome List [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) export default `# <%= username %> Awesome List [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)
> :star: generated with [simonecorsi/mawesome](https://github.com/simonecorsi/mawesome) > :star: generated with [simonecorsi/mawesome](https://github.com/simonecorsi/mawesome)
@@ -11,3 +11,4 @@
<% } %> <% } %>
<% } %> <% } %>
`;

52
test/helpers.spec.ts Normal file
View 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);
});