diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index a822f5f5dc..e13c8847b1 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -3,12 +3,12 @@ name: Benchmark on: push: paths: - - 'lib/**' + - "lib/**" pull_request: branches: - master paths-ignore: - - 'test/scripts/**' + - "test/scripts/**" jobs: benchmark: @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: ['14', '16', '18'] + node-version: ["14", "16", "18"] fail-fast: false steps: - uses: actions/checkout@v4 @@ -28,13 +28,16 @@ jobs: run: npm install --silent - name: Running benchmark run: node test/benchmark.js --benchmark + profiling: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest] - node-version: ['14', '16', '18'] + node-version: ["14", "16", "18"] fail-fast: false + env: + comment_file: ".tmp-comment-flamegraph-node${{ matrix.node-version }}.md" steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} @@ -52,8 +55,30 @@ jobs: project: ./.tmp-hexo-theme-unit-test/0x/ login: ${{ secrets.SURGE_LOGIN }} token: ${{ secrets.SURGE_TOKEN }} - - name: Comment PR - uses: marocchino/sticky-pull-request-comment@v2 + + - name: save comment to file + if: ${{github.event_name == 'pull_request' }} + run: | + echo "https://${{ github.sha }}-${{ matrix.node-version }}-hexo.surge.sh/flamegraph.html" > ${{env.comment_file}} + + - uses: actions/upload-artifact@v4 + if: ${{github.event_name == 'pull_request' }} + with: + retention-days: 1 + name: comment-node${{ matrix.node-version }} + path: ${{env.comment_file}} + + number: + runs-on: ubuntu-latest + if: ${{github.event_name == 'pull_request' }} + env: + pr_number_file: .tmp-comment-pr_number + steps: + - name: save PR number to file + run: | + echo -n "${{ github.event.number }}" > ${{env.pr_number_file}} + - uses: actions/upload-artifact@v4 with: - message: | - Publish flamegraph to https://${{ github.sha }}-${{ matrix.node-version }}-hexo.surge.sh/flamegraph.html + retention-days: 1 + name: comment-pr_number + path: ${{env.pr_number_file}} diff --git a/.github/workflows/commenter.yml b/.github/workflows/commenter.yml index f449809a30..1568d8d79e 100644 --- a/.github/workflows/commenter.yml +++ b/.github/workflows/commenter.yml @@ -1,19 +1,27 @@ name: Commenter -on: [pull_request_target] +on: + pull_request_target: + + workflow_run: + workflows: ["Benchmark"] + types: + - completed permissions: contents: read jobs: - commenter: + comment-test: permissions: - pull-requests: write # for marocchino/sticky-pull-request-comment to create or update PR comment + pull-requests: write # for marocchino/sticky-pull-request-comment to create or update PR comment runs-on: ubuntu-latest + if: ${{github.event_name == 'pull_request_target' }} steps: - - name: Comment PR + - name: Comment PR - How to test uses: marocchino/sticky-pull-request-comment@v2 with: + header: How to test message: | ## How to test @@ -23,3 +31,38 @@ jobs: npm install npm test ``` + + comment-flamegraph: + permissions: + pull-requests: write # for marocchino/sticky-pull-request-comment to create or update PR comment + actions: read # get artifact + runs-on: ubuntu-latest + if: ${{github.event_name == 'workflow_run' }} + env: + comment_result: ".tmp-comment-flamegraph.md" + steps: + - name: download artifact + uses: actions/download-artifact@v4 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + run-id: ${{toJSON(github.event.workflow_run.id)}} + pattern: "comment-*" + merge-multiple: true + + - name: get PR number + run: | + echo "pr_number=$(cat .tmp-comment-pr_number)" >> "$GITHUB_ENV" + + - name: combime comment + run: | + echo "## flamegraph" > ${{env.comment_result}} + echo "" >> ${{env.comment_result}} + cat .tmp-comment-flamegraph-*.md >> ${{env.comment_result}} + + - name: Comment PR - flamegraph + uses: marocchino/sticky-pull-request-comment@v2 + with: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + number: ${{env.pr_number}} + header: flamegraph + path: ${{env.comment_result}} diff --git a/lib/hexo/index.ts b/lib/hexo/index.ts index 8fd4f32c55..2da92f6b90 100644 --- a/lib/hexo/index.ts +++ b/lib/hexo/index.ts @@ -163,6 +163,88 @@ declare module 'module' { _cache: any; } +interface Hexo { + + /** + * Emitted before deployment begins. + * @param event + * @param listener + * @link https://hexo.io/api/events.html#deployBefore + */ + on(event: 'deployBefore', listener: (...args: any[]) => any): this; + + /** + * Emitted after deployment begins. + * @param event + * @param listener + * @link https://hexo.io/api/events.html#deployAfter + */ + on(event: 'deployAfter', listener: (...args: any[]) => any): this; + + /** + * Emitted before Hexo exits. + * @param event + * @param listener + * @link https://hexo.io/api/events.html#exit + */ + on(event: 'exit', listener: (...args: any[]) => any): this; + + /** + * Emitted before generation begins. + * @param event + * @param listener + * @link https://hexo.io/api/events.html#generateBefore + */ + on(event: 'generateBefore', listener: (...args: any[]) => any): this; + + /** + * Emitted after generation finishes. + * @param event + * @param listener + * @link https://hexo.io/api/events.html#generateAfter + */ + on(event: 'generateAfter', listener: (...args: any[]) => any): this; + + /** + * Emitted after a new post has been created. This event returns the post data: + * @param event + * @param listener + * @link https://hexo.io/api/events.html#new + */ + on(event: 'new', listener: (post: { path: string; content: string; }) => any): this; + + /** + * Emitted before processing begins. This event returns a path representing the root directory of the box. + * @param event + * @param listener + * @link https://hexo.io/api/events.html#processBefore + */ + on(event: 'processBefore', listener: (...args: any[]) => any): this; + + /** + * Emitted after processing finishes. This event returns a path representing the root directory of the box. + * @param event + * @param listener + * @link https://hexo.io/api/events.html#processAfter + */ + on(event: 'processAfter', listener: (...args: any[]) => any): this; + + /** + * Emitted after initialization finishes. + * @param event + * @param listener + */ + on(event: 'ready', listener: (...args: any[]) => any): this; + + /** + * undescripted on emit + * @param event + * @param listener + */ + on(event: string, listener: (...args: any[]) => any): any; + emit(event: string, ...args: any[]): any; +} + class Hexo extends EventEmitter { public base_dir: string; public public_dir: string; diff --git a/lib/hexo/multi_config_path.ts b/lib/hexo/multi_config_path.ts index f17e332532..27c9babd78 100644 --- a/lib/hexo/multi_config_path.ts +++ b/lib/hexo/multi_config_path.ts @@ -62,7 +62,7 @@ export = (ctx: Hexo) => function multiConfigPath(base: string, configPaths: stri return defaultPath; } - log.i('Config based on', count, 'files'); + log.i('Config based on', count.toString(), 'files'); const multiconfigRoot = outputDir || base; const outputPath = join(multiconfigRoot, '_multiconfig.yml'); diff --git a/lib/plugins/console/generate.ts b/lib/plugins/console/generate.ts index 721a9e8539..f6bfcd67a7 100644 --- a/lib/plugins/console/generate.ts +++ b/lib/plugins/console/generate.ts @@ -181,7 +181,7 @@ class Generater { const interval = prettyHrtime(process.hrtime(this.start)); const count = result.filter(Boolean).length; - log.info('%d files generated in %s', count, cyan(interval)); + log.info('%d files generated in %s', count.toString(), cyan(interval)); }); } execWatch(): Promise { diff --git a/lib/plugins/tag/post_link.ts b/lib/plugins/tag/post_link.ts index 577b1319ef..67289df469 100644 --- a/lib/plugins/tag/post_link.ts +++ b/lib/plugins/tag/post_link.ts @@ -10,11 +10,19 @@ import type Hexo from '../../hexo'; */ export = (ctx: Hexo) => { return function postLinkTag(args: string[]) { - const slug = args.shift(); + let slug = args.shift(); if (!slug) { throw new Error(`Post not found: "${slug}" doesn't exist for {% post_link %}`); } + let hash = ''; + const parts = slug.split('#'); + + if (parts.length === 2) { + slug = parts[0]; + hash = parts[1]; + } + let escape = args[args.length - 1]; if (escape === 'true' || escape === 'false') { args.pop(); @@ -33,7 +41,8 @@ export = (ctx: Hexo) => { const attrTitle = escapeHTML(post.title || post.slug); if (escape === 'true') title = escapeHTML(title); - const link = encodeURL(new URL(post.path, ctx.config.url).pathname); + const url = new URL(post.path, ctx.config.url).pathname + (hash ? `#${hash}` : ''); + const link = encodeURL(url); return `${title}`; }; diff --git a/package.json b/package.json index a92319e548..544c8f9fe7 100644 --- a/package.json +++ b/package.json @@ -72,10 +72,8 @@ "@types/node": "^18.11.8", "@types/nunjucks": "^3.2.2", "@types/text-table": "^0.2.4", - "@typescript-eslint/eslint-plugin": "^5.41.0", - "@typescript-eslint/parser": "^5.41.0", "0x": "^5.1.2", - "c8": "^8.0.0", + "c8": "^9.0.0", "chai": "^4.3.6", "cheerio": "0.22.0", "decache": "^4.6.1", @@ -87,7 +85,7 @@ "mocha": "^10.0.0", "sinon": "^15.0.0", "ts-node": "^10.9.1", - "typescript": "^4.8.4" + "typescript": "^5.3.2" }, "engines": { "node": ">=14" diff --git a/test/scripts/tags/post_link.js b/test/scripts/tags/post_link.js index 999f2cad48..05839a8098 100644 --- a/test/scripts/tags/post_link.js +++ b/test/scripts/tags/post_link.js @@ -73,4 +73,8 @@ describe('post_link', () => { it('should throw if post not found', () => { should.throw(() => postLink(['bar']), Error, /Post not found: post_link bar\./); }); + + it('should keep hash', () => { + postLink(['foo#bar']).should.eql('Hello world'); + }); });