chore: add context7.json to control documentation indexing #252
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 'Discord: repo activity' | |
| on: | |
| push: | |
| branches: ['**'] | |
| workflow_dispatch: | |
| inputs: | |
| before: | |
| description: 'Old tip SHA (exclusive)' | |
| required: true | |
| type: string | |
| after: | |
| description: 'New tip SHA (inclusive)' | |
| required: true | |
| type: string | |
| jobs: | |
| notify: | |
| if: github.actor != 'dependabot[bot]' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| # ---------------------------------------------------------------------- | |
| # Build the per-commit lines. | |
| # | |
| # Wire format per line (one commit): | |
| # N. **`type(scope):`** subject · [`abc1234`](url) · author | |
| # | |
| # Notes for future maintainers (and for whoever reads this from the | |
| # Discord side): | |
| # - We render the SUBJECT only. Bodies are intentionally omitted — | |
| # they fragment readability in chat and the hash link gives the | |
| # full git show one click away. | |
| # - The previous version stripped (), [], and ` from the message to | |
| # "protect" the [hash](url) link that follows. That was a false | |
| # positive: Discord's link parser only triggers on `]` IMMEDIATELY | |
| # followed by `(`, and our hash link sits behind a ` · ` separator | |
| # so subject-side punctuation is safe. Stripping parens turned | |
| # `fix(editor):` into `fixeditor:` and is the bug we are fixing. | |
| # - Conventional Commit prefix (type, optional scope, optional !) | |
| # is detected with a single capture and rendered as bold inline | |
| # code so it pops without breaking non-conventional commits. | |
| # - Control characters (\u0000-\u001f) are still stripped because | |
| # they break Discord rendering and have no legitimate place in a | |
| # commit subject. | |
| # - GitHub push webhooks include at most 20 commits in | |
| # github.event.commits. For larger pushes we load the full range | |
| # via the compare API (repos/.../compare/before...after). | |
| # - Deploy-trigger subjects (`(build): …`) are dropped from the | |
| # list. Conventional `build(scope):` stays. A push that is only | |
| # triggers does not post. | |
| # ---------------------------------------------------------------------- | |
| - name: Build commit summary (for push) | |
| id: build | |
| env: | |
| EVENT_JSON: ${{ toJSON(github.event) }} | |
| GH_TOKEN: ${{ github.token }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| DISPATCH_BEFORE: ${{ inputs.before }} | |
| DISPATCH_AFTER: ${{ inputs.after }} | |
| REF_NAME: ${{ github.ref_name }} | |
| run: | | |
| REPO="${{ github.repository }}" | |
| ZERO_SHA="0000000000000000000000000000000000000000" | |
| is_sha() { [[ "$1" =~ ^[0-9a-f]{7,40}$ ]]; } | |
| if [ "$EVENT_NAME" = "workflow_dispatch" ]; then | |
| BEFORE="$DISPATCH_BEFORE" | |
| AFTER="$DISPATCH_AFTER" | |
| if ! is_sha "$BEFORE" || ! is_sha "$AFTER"; then | |
| echo "::error::before/after must be git SHAs" | |
| exit 1 | |
| fi | |
| REF="$REF_NAME" | |
| COMPARE="https://github.com/${REPO}/compare/${BEFORE}...${AFTER}" | |
| else | |
| REF=$(jq -r '.ref' <<< "$EVENT_JSON" | sed 's|refs/heads/||') | |
| COMPARE=$(jq -r '.compare' <<< "$EVENT_JSON") | |
| BEFORE="${{ github.event.before }}" | |
| AFTER="${{ github.event.after }}" | |
| fi | |
| normalize_webhook() { | |
| jq '{ | |
| commits: [ | |
| .commits[]? | { | |
| id: .id, | |
| message: .message, | |
| author: {name: (.author.name // "unknown")} | |
| } | |
| ] | |
| }' <<< "$EVENT_JSON" | |
| } | |
| if [ "$EVENT_NAME" = "workflow_dispatch" ]; then | |
| API_PAGES=$(gh api "repos/${REPO}/compare/${BEFORE}...${AFTER}" --paginate 2>/dev/null) || API_PAGES="" | |
| if [ -z "$API_PAGES" ]; then | |
| echo "::error::compare API failed for ${BEFORE}...${AFTER}" | |
| exit 1 | |
| fi | |
| COMMITS_JSON=$(jq -s ' | |
| [.[].commits[]?] | |
| | unique_by(.sha) | |
| | {commits: map({ | |
| id: .sha, | |
| message: .commit.message, | |
| author: {name: (.commit.author.name // "unknown")} | |
| })} | |
| ' <<< "$API_PAGES") | |
| elif [ "$BEFORE" = "$ZERO_SHA" ] || [ -z "$BEFORE" ]; then | |
| COMMITS_JSON=$(normalize_webhook) | |
| else | |
| API_PAGES=$(gh api "repos/${REPO}/compare/${BEFORE}...${AFTER}" --paginate 2>/dev/null) || API_PAGES="" | |
| if [ -n "$API_PAGES" ]; then | |
| COMMITS_JSON=$(jq -s ' | |
| [.[].commits[]?] | |
| | unique_by(.sha) | |
| | {commits: map({ | |
| id: .sha, | |
| message: .commit.message, | |
| author: {name: (.commit.author.name // "unknown")} | |
| })} | |
| ' <<< "$API_PAGES") | |
| if [ "$(jq -r '.commits | length' <<< "$COMMITS_JSON")" -eq 0 ]; then | |
| COMMITS_JSON=$(normalize_webhook) | |
| fi | |
| else | |
| echo "::warning::compare API failed; falling back to webhook commits (max 20)" | |
| COMMITS_JSON=$(normalize_webhook) | |
| fi | |
| fi | |
| # Same prefix the deploy tokenizer treats as a trigger. Do not | |
| # key the skip on head_commit alone — a mixed push would still | |
| # print the `(build):` lines. | |
| COMMITS_JSON=$(jq ' | |
| .commits |= map(select( | |
| (.message // "" | |
| | split("\n")[0] | |
| | gsub("^\\s+|\\s+$"; "") | |
| | startswith("(build)") | |
| | not) | |
| )) | |
| ' <<< "$COMMITS_JSON") | |
| COUNT=$(jq -r '.commits | length' <<< "$COMMITS_JSON") | |
| REPO_URL="https://github.com/${REPO}" | |
| jq -r --arg repo "$REPO_URL" ' | |
| .commits | to_entries[] | | |
| ((1 + .key) | tostring) as $n | | |
| (.value.id[0:7]) as $sha | | |
| ($repo + "/commit/" + .value.id) as $url | | |
| (.value.message | |
| | split("\n")[0] | |
| | gsub("[\u0000-\u001f]"; " ") | |
| | gsub("\\s+"; " ") | |
| | gsub("^\\s+|\\s+$"; "") | |
| ) as $subject | | |
| ([$subject | |
| | capture("^(?<prefix>[a-zA-Z]+(?:\\([^)]+\\))?!?:)\\s*(?<rest>.*)$") | |
| ] | .[0]) as $cc | | |
| (if $cc != null then | |
| "**`" + $cc.prefix + "`** " + ($cc.rest | .[0:180]) | |
| else | |
| ($subject | .[0:200]) | |
| end) as $title | | |
| $n + ". " + $title + " · [`" + $sha + "`](" + $url + ") · " + .value.author.name | |
| ' <<< "$COMMITS_JSON" > /tmp/commits.txt | |
| { | |
| echo "COUNT=$COUNT" | |
| echo "REF=$REF" | |
| echo "COMPARE=$COMPARE" | |
| } >> "$GITHUB_ENV" | |
| # ---------------------------------------------------------------------- | |
| # Post to Discord. | |
| # | |
| # Splitting: | |
| # Discord caps content at 2000 chars. We pack as many commit lines as | |
| # fit under MAX_LEN (1900, leaving ~100 char buffer for trailing JSON | |
| # and a bit of slack), then flush. The HEADER is only included in the | |
| # first chunk. Later chunks are more numbered lines, with no marker. | |
| # | |
| # flags: 4 == SUPPRESS_EMBEDS — keeps the message compact (no GitHub | |
| # link previews stacking under every commit). | |
| # ---------------------------------------------------------------------- | |
| - name: Post to Discord (smart split) | |
| env: | |
| DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} | |
| run: | | |
| if [ -z "$DISCORD_WEBHOOK" ]; then | |
| echo "::warning::DISCORD_WEBHOOK is empty; skip post" | |
| exit 0 | |
| fi | |
| if [ "${COUNT:-0}" -eq 0 ]; then | |
| echo "no non-trigger commits; skip post" | |
| exit 0 | |
| fi | |
| HEADER="🚀 **Push** to \`${{ env.REF }}\` by \`${{ github.actor }}\` | |
| 📦 \`${{ github.repository }}\` · 📝 ${{ env.COUNT }} commits · 🔗 [View Diff](${{ env.COMPARE }}) | |
| **Commits** | |
| " | |
| MAX_LEN=1900 | |
| CURRENT_CHUNK="" | |
| CHUNK_NUM=1 | |
| send_chunk() { | |
| local message="$1" | |
| curl -sS -H "Content-Type: application/json" \ | |
| -d "{\"content\": $(printf '%s' "$message" | jq -Rs .), \"flags\": 4}" \ | |
| "$DISCORD_WEBHOOK" | |
| sleep 1 | |
| } | |
| while IFS= read -r line || [ -n "$line" ]; do | |
| [ -z "$line" ] && continue | |
| TEST_MSG="${HEADER}${CURRENT_CHUNK}${line}"$'\n' | |
| if [ ${#TEST_MSG} -gt $MAX_LEN ] && [ -n "$CURRENT_CHUNK" ]; then | |
| if [ $CHUNK_NUM -eq 1 ]; then | |
| send_chunk "${HEADER}${CURRENT_CHUNK}" | |
| else | |
| send_chunk "${CURRENT_CHUNK}" | |
| fi | |
| CHUNK_NUM=$((CHUNK_NUM + 1)) | |
| CURRENT_CHUNK="${line}"$'\n' | |
| else | |
| CURRENT_CHUNK="${CURRENT_CHUNK}${line}"$'\n' | |
| fi | |
| done < /tmp/commits.txt | |
| if [ -n "$CURRENT_CHUNK" ]; then | |
| if [ $CHUNK_NUM -eq 1 ]; then | |
| send_chunk "${HEADER}${CURRENT_CHUNK}" | |
| else | |
| send_chunk "${CURRENT_CHUNK}" | |
| fi | |
| fi |