@@ -317,205 +317,82 @@ jobs:
317317 env :
318318 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
319319
320- notify :
321- name : Send Release Notifications
322- runs-on : ubuntu-latest
320+ notify-discussion :
321+ name : Create GitHub Discussion
323322 needs : release
324-
325- steps :
326- - name : Checkout code
327- uses : actions/checkout@v4
328-
329- - name : Create GitHub Discussion Announcement
330- id : discussion
331- run : |
332- VERSION="${{ github.event.inputs.version }}"
333- RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/v$VERSION"
334- REPO_URL="https://github.com/${{ github.repository }}"
335-
336- # Get repository ID and Announcements category ID
337- REPO_DATA=$(gh api graphql -f query='
338- query($owner: String!, $repo: String!) {
339- repository(owner: $owner, name: $repo) {
340- id
341- discussionCategories(first: 10) {
342- nodes {
343- id
344- name
345- }
346- }
347- }
348- }
349- ' -f owner="${{ github.repository_owner }}" -f repo="${{ github.event.repository.name }}")
350-
351- REPO_ID=$(echo "$REPO_DATA" | jq -r '.data.repository.id')
352- CATEGORY_ID=$(echo "$REPO_DATA" | jq -r '.data.repository.discussionCategories.nodes[] | select(.name == "Announcements") | .id')
353-
354- if [ -z "$CATEGORY_ID" ]; then
355- echo "Error: Could not find Announcements category"
356- exit 1
357- fi
358-
359- echo "Repository ID: $REPO_ID"
360- echo "Announcements Category ID: $CATEGORY_ID"
361-
362- # Create discussion body (build it with string concatenation to avoid heredoc issues)
363- DISCUSSION_BODY="## Changes in this release"
364- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"See the [full changelog](RELEASE_URL_PLACEHOLDER) for details on what's new in this release."
365- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"## Installation"
366- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"### Quick Install (Recommended)"
367- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"**macOS / Linux:**"
368- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n''```bash'
369- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n'"curl -fsSL REPO_URL_PLACEHOLDER/releases/download/vVERSION_PLACEHOLDER/install.sh | bash"
370- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n''```'
371- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"**Windows (PowerShell):**"
372- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n''```powershell'
373- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n'"irm REPO_URL_PLACEHOLDER/releases/download/vVERSION_PLACEHOLDER/install.ps1 | iex"
374- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n''```'
375- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"### Manual Installation"
376- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"1. Download the appropriate archive for your platform from the [release page](RELEASE_URL_PLACEHOLDER)"
377- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n'"2. Extract the archive"
378- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n'"3. Move binaries to a directory in your PATH"
379- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n'"4. Run \`dtvem init\` to complete setup"
380- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"## Supported Platforms"
381- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"- ✅ Windows (amd64, arm64)"
382- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n'"- ✅ macOS (amd64, arm64/Apple Silicon)"
383- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n'"- ✅ Linux (amd64)"
384- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"---"
385- DISCUSSION_BODY="$DISCUSSION_BODY"$'\n\n'"📦 [View Release](RELEASE_URL_PLACEHOLDER) | 📖 [Documentation](REPO_URL_PLACEHOLDER)"
386- # Replace placeholders with actual values
387- DISCUSSION_BODY="${DISCUSSION_BODY//RELEASE_URL_PLACEHOLDER/$RELEASE_URL}"
388- DISCUSSION_BODY="${DISCUSSION_BODY//REPO_URL_PLACEHOLDER/$REPO_URL}"
389- DISCUSSION_BODY="${DISCUSSION_BODY//VERSION_PLACEHOLDER/${{ github.event.inputs.version }}}"
390-
391- # Create the discussion
392- DISCUSSION_RESULT=$(gh api graphql -f query='
393- mutation($repositoryId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
394- createDiscussion(input: {
395- repositoryId: $repositoryId
396- categoryId: $categoryId
397- title: $title
398- body: $body
399- }) {
400- discussion {
401- url
402- }
403- }
404- }
405- ' -f repositoryId="$REPO_ID" -f categoryId="$CATEGORY_ID" -f title="🎉 dtvem v$VERSION has been released!" -f body="$DISCUSSION_BODY")
406-
407- DISCUSSION_URL=$(echo "$DISCUSSION_RESULT" | jq -r '.data.createDiscussion.discussion.url')
408- echo "✓ Created discussion: $DISCUSSION_URL"
409- echo "discussion_url=$DISCUSSION_URL" >> $GITHUB_OUTPUT
410- shell : bash
411- env :
412- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
413-
414- - name : Post to BlueSky
415- run : |
416- VERSION="${{ github.event.inputs.version }}"
417- RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/v$VERSION"
418- DISCUSSION_URL="${{ steps.discussion.outputs.discussion_url }}"
419-
420- # Discover runtimes from src/runtimes/ directory
421- RUNTIME_DIRS=$(find src/runtimes -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort)
422-
423- # Capitalize runtime names
424- RUNTIME_LIST=()
425- for runtime in $RUNTIME_DIRS; do
426- RUNTIME_LIST+=("${runtime^}") # Capitalize first letter
427- done
428-
429- # Format runtime names based on count (with hashtags)
430- RUNTIME_COUNT=${#RUNTIME_LIST[@]}
431- if [ $RUNTIME_COUNT -eq 1 ]; then
432- RUNTIME_NAMES="#${RUNTIME_LIST[0]}"
433- elif [ $RUNTIME_COUNT -eq 2 ]; then
434- RUNTIME_NAMES="#${RUNTIME_LIST[0]} and #${RUNTIME_LIST[1]}"
435- else
436- # Three or more: "#A, #B, and #C"
437- RUNTIME_NAMES=""
438- for i in "${!RUNTIME_LIST[@]}"; do
439- if [ $i -eq 0 ]; then
440- RUNTIME_NAMES="#${RUNTIME_LIST[$i]}"
441- elif [ $i -eq $((RUNTIME_COUNT - 1)) ]; then
442- RUNTIME_NAMES="${RUNTIME_NAMES}, and #${RUNTIME_LIST[$i]}"
443- else
444- RUNTIME_NAMES="${RUNTIME_NAMES}, #${RUNTIME_LIST[$i]}"
445- fi
446- done
447- fi
448-
449- echo "Detected runtimes: $RUNTIME_NAMES"
450-
451- # Authenticate with BlueSky
452- echo "Authenticating with BlueSky..."
453- AUTH_RESPONSE=$(curl -s -X POST https://bsky.social/xrpc/com.atproto.server.createSession \
454- -H "Content-Type: application/json" \
455- -d "{\"identifier\": \"${{ secrets.BLUESKY_USERNAME }}\", \"password\": \"${{ secrets.BLUESKY_APP_PASSWORD }}\"}")
456-
457- ACCESS_TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.accessJwt')
458- DID=$(echo "$AUTH_RESPONSE" | jq -r '.did')
459-
460- if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" == "null" ]; then
461- echo "Error: Failed to authenticate with BlueSky"
462- echo "Response: $AUTH_RESPONSE"
463- exit 1
464- fi
465-
466- echo "✓ Authenticated as $DID"
467-
468- # Create post text (must be under 300 graphemes)
469- POST_TEXT="🚀 #dtvem v${VERSION} is now available!"
470- POST_TEXT="${POST_TEXT}"$'\n\n'"Cross-platform version manager for ${RUNTIME_NAMES} - supports #Windows, #Linux, and #MacOS"
471- POST_TEXT="${POST_TEXT}"$'\n\n'"Release: ${RELEASE_URL}"
472- POST_TEXT="${POST_TEXT}"$'\n'"Discuss: ${DISCUSSION_URL}"
473-
474- echo "Post text: $POST_TEXT"
475- echo "Post length: $(echo -n "$POST_TEXT" | wc -c) characters"
476-
477- # Get current timestamp in ISO 8601 format
478- TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
479-
480- # Calculate facets (byte positions for hashtags and links)
481- echo "Calculating facets for links and hashtags..."
482- export POST_TEXT
483- FACETS=$(python3 -c "import json; import re; import os; text = os.environ['POST_TEXT']; facets = []; [facets.append({'index': {'byteStart': len(text[:m.start()].encode('utf-8')), 'byteEnd': len(text[:m.start()+len(m.group(0))].encode('utf-8'))}, 'features': [{'\$type': 'app.bsky.richtext.facet#tag', 'tag': m.group(1)}]}) for m in re.finditer(r'#(\w+)', text)]; [facets.append({'index': {'byteStart': len(text[:m.start()].encode('utf-8')), 'byteEnd': len(text[:m.start()+len(m.group())].encode('utf-8'))}, 'features': [{'\$type': 'app.bsky.richtext.facet#link', 'uri': m.group()}]}) for m in re.finditer(r'https?://[^\s]+', text)]; print(json.dumps(facets))")
484-
485- echo "Facets: $FACETS"
486-
487- # Create the post using jq to properly escape JSON
488- echo "Creating BlueSky post..."
489- POST_RESPONSE=$(jq -n \
490- --arg did "$DID" \
491- --arg text "$POST_TEXT" \
492- --arg timestamp "$TIMESTAMP" \
493- --argjson facets "$FACETS" \
494- '{
495- repo: $did,
496- collection: "app.bsky.feed.post",
497- record: {
498- text: $text,
499- facets: $facets,
500- createdAt: $timestamp,
501- "$type": "app.bsky.feed.post"
502- }
503- }' | curl -s -X POST https://bsky.social/xrpc/com.atproto.repo.createRecord \
504- -H "Content-Type: application/json" \
505- -H "Authorization: Bearer $ACCESS_TOKEN" \
506- -d @-)
507-
508- POST_URI=$(echo "$POST_RESPONSE" | jq -r '.uri')
509-
510- if [ -z "$POST_URI" ] || [ "$POST_URI" == "null" ]; then
511- echo "Error: Failed to create BlueSky post"
512- echo "Response: $POST_RESPONSE"
513- exit 1
514- fi
515-
516- # Extract the post ID from the URI (format: at://did:plc:.../app.bsky.feed.post/POST_ID)
517- POST_ID=$(echo "$POST_URI" | sed 's|.*/||')
518- POST_URL="https://bsky.app/profile/${{ secrets.BLUESKY_USERNAME }}/post/$POST_ID"
519-
520- echo "✓ Posted to BlueSky: $POST_URL"
521- shell : bash
323+ uses : CodingWithCalvin/.github/.github/workflows/github-discussion.yml@main
324+ with :
325+ title : " 🎉 dtvem v${{ github.event.inputs.version }} has been released!"
326+ body : |
327+ ## Changes in this release
328+
329+ See the [full changelog](https://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }}) for details on what's new in this release.
330+
331+ ## Installation
332+
333+ ### Quick Install (Recommended)
334+
335+ **macOS / Linux:**
336+ ```bash
337+ curl -fsSL https://github.com/${{ github.repository }}/releases/download/v${{ github.event.inputs.version }}/install.sh | bash
338+ ```
339+
340+ **Windows (PowerShell):**
341+ ```powershell
342+ irm https://github.com/${{ github.repository }}/releases/download/v${{ github.event.inputs.version }}/install.ps1 | iex
343+ ```
344+
345+ ### Manual Installation
346+
347+ 1. Download the appropriate archive for your platform from the [release page](https://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }})
348+ 2. Extract the archive
349+ 3. Move binaries to a directory in your PATH
350+ 4. Run `dtvem init` to complete setup
351+
352+ ## Supported Platforms
353+
354+ - ✅ Windows (amd64, arm64)
355+ - ✅ macOS (amd64, arm64/Apple Silicon)
356+ - ✅ Linux (amd64)
357+
358+ ---
359+
360+ 📦 [View Release](https://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }}) | 📖 [Documentation](https://github.com/${{ github.repository }})
361+
362+ notify-bluesky :
363+ name : Post to Bluesky
364+ needs : notify-discussion
365+ uses : CodingWithCalvin/.github/.github/workflows/bluesky-post.yml@main
366+ with :
367+ post_text : |
368+ 🚀 #dtvem v${{ github.event.inputs.version }} is now available!
369+
370+ Cross-platform version manager for #Node, #Python, and #Ruby - supports #Windows, #Linux, and #macOS
371+
372+ [Release Notes](https://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }})
373+ [Discussion](${{ needs.notify-discussion.outputs.discussion_url }})
374+ embed_url : https://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }}
375+ embed_title : dtvem v${{ github.event.inputs.version }}
376+ embed_description : Cross-platform runtime version manager for Node.js, Python, and Ruby
377+ secrets :
378+ BLUESKY_USERNAME : ${{ secrets.BLUESKY_USERNAME }}
379+ BLUESKY_APP_PASSWORD : ${{ secrets.BLUESKY_APP_PASSWORD }}
380+
381+ notify-linkedin :
382+ name : Post to LinkedIn
383+ needs : notify-discussion
384+ uses : CodingWithCalvin/.github/.github/workflows/linkedin-post.yml@main
385+ with :
386+ post_text : |
387+ 🚀 #dtvem v${{ github.event.inputs.version }} is now available!
388+
389+ Cross-platform version manager for #Node, #Python, and #Ruby - supports #Windows, #Linux, and #macOS
390+
391+ Release Notes: https://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }}
392+ Discussion: ${{ needs.notify-discussion.outputs.discussion_url }}
393+ article_url : https://github.com/${{ github.repository }}/releases/tag/v${{ github.event.inputs.version }}
394+ article_title : dtvem v${{ github.event.inputs.version }}
395+ article_description : Cross-platform runtime version manager for Node.js, Python, and Ruby
396+ secrets :
397+ LINKEDIN_ACCESS_TOKEN : ${{ secrets.LINKEDIN_ACCESS_TOKEN }}
398+ LINKEDIN_CLIENT_ID : ${{ secrets.LINKEDIN_CLIENT_ID }}
0 commit comments