mirror of
https://github.com/nexu-io/open-design.git
synced 2026-09-20 06:15:06 +08:00
88d1eab743
* feat(landing): surface user-submitted tutorial issues and PRs in the digest User submissions lived only on GitHub and never entered the daily review flow. The tutorials-youtube-sync digest now also lists them so they're reviewed alongside auto-discovered YouTube candidates: - Submission issues: open issues from the 'Submit a tutorial' form (label tutorials). The card shows each with the video link extracted from the body; on approval a maintainer generates the entry and opens a PR (Closes #issue). - Contribution PRs: open PRs touching app/content/tutorials/** are auto-labeled 'tutorials' by a new labeler workflow, and listed in the card for review/merge on GitHub. Adds github-submissions.ts (search-API fetch + video-URL extraction) with unit tests, two new Feishu card sections, issues:read + pull-requests:read on the workflow, and the labeler workflow/config. Submission lookup is non-fatal — a failure skips those sections without affecting the YouTube candidates. * fix(landing): fail on submission lookup error; broaden YouTube URL parsing Per review: - A failed submission search no longer silently posts a digest without the issue/PR sections. It now aborts before posting (exit non-zero, observable); submissions aren't windowed so the next run re-queries them, and YouTube candidates are re-covered via the unchanged watermark — nothing is lost. - Extract a shared extractYouTubeId() (watch incl. m.youtube, youtu.be, embed, shorts, live) used by both the submission parser and generate-selected, so the digest no longer mislabels shorts/mobile links as 'no video link'. videoUrl is canonicalized to youtu.be/<id>. - Tests: shorts + mobile-watch extraction, and that a failed search rejects (is not swallowed). * fix(landing): host-anchor extractYouTubeId to real YouTube hosts Per review: the broadened matcher accepted ?v=<id> on any host, so a non-YouTube link like https://example.com/watch?v=... was canonicalized to a youtu.be URL and hid invalid submissions. Require a YouTube host (youtube.com / m. / music. / youtu.be) before accepting v=/shorts/embed/live. Add a regression test that a non-YouTube ?v= URL leaves videoUrl undefined. * fix(landing): validate YouTube host via URL hostname, not substring Per review: the substring host check matched lookalikes (notyoutube.com, evil-youtube.com). extractYouTubeId now parses candidate URLs with new URL() and checks hostname against an allowlist (youtu.be, youtube.com, www/m/music .youtube.com) before extracting the id. Regression fixtures for non-YouTube and lookalike hosts. * fix(ci): grant issues:write to labeler so it can create the tutorials label Per review: actions/labeler needs issue-label write to create the tutorials label when missing. The label is also pre-created in the repo so the issue-submission form can apply it; this makes first-run deterministic. * fix(landing): sync tutorials label to live diff; paginate submission search Per review: - labeler: sync-labels: true so the tutorials label is removed when a PR no longer touches the tutorials content dir, keeping the digest's is:pr label:tutorials query free of stale/non-tutorial PRs. - searchIssues paginates (per_page=100, loops until a short page, 10-page cap) so a backlog over one page is not silently truncated. Test stubs two pages. --------- Co-authored-by: Joey <276262049+xne998808-ai@users.noreply.github.com>
33 lines
1.1 KiB
YAML
33 lines
1.1 KiB
YAML
name: labeler
|
|
|
|
# Auto-applies the `tutorials` label to PRs that touch the tutorials content
|
|
# directory, so the scheduled tutorials-youtube-sync digest can list community
|
|
# tutorial contributions for review. Config: .github/labeler.yml.
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, synchronize, reopened]
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
# actions/labeler needs issue-label write to create the `tutorials` label if
|
|
# it does not yet exist before applying it (the label is also pre-created in
|
|
# the repo so the issue-submission form can apply it too).
|
|
issues: write
|
|
|
|
concurrency:
|
|
group: labeler-${{ github.event.pull_request.number }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
label:
|
|
if: github.repository == 'nexu-io/open-design'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/labeler@v5
|
|
with:
|
|
# Keep the `tutorials` label in sync with the live diff: remove it if a
|
|
# PR no longer touches the tutorials content dir, so the digest's
|
|
# `is:pr label:tutorials` query never lists stale, non-tutorial PRs.
|
|
sync-labels: true
|