@@ -43,3 +43,107 @@ jobs:
4343 marketplace-pat : ${{ secrets.VS_PAT }}
4444 publish-manifest-path : ./resources/extension.manifest.json
4545 vsix-path : ./artifact/CodingWithCalvin.OpenInNotepadPlusPlus.vsix
46+
47+ - name : 5. Post to BlueSky
48+ if : success()
49+ run : |
50+ VERSION="${{ steps.artifact_manifest.outputs.version }}"
51+ RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/$VERSION"
52+ MARKETPLACE_URL="https://marketplace.visualstudio.com/items?itemName=CodingWithCalvin.VS-OpenInNotepadPlusPlus"
53+
54+ # Authenticate with BlueSky
55+ echo "Authenticating with BlueSky..."
56+ AUTH_RESPONSE=$(curl -s -X POST https://bsky.social/xrpc/com.atproto.server.createSession \
57+ -H "Content-Type: application/json" \
58+ -d "{\"identifier\": \"${{ secrets.BLUESKY_USERNAME }}\", \"password\": \"${{ secrets.BLUESKY_APP_PASSWORD }}\"}")
59+
60+ ACCESS_TOKEN=$(echo "$AUTH_RESPONSE" | jq -r '.accessJwt')
61+ DID=$(echo "$AUTH_RESPONSE" | jq -r '.did')
62+
63+ if [ -z "$ACCESS_TOKEN" ] || [ "$ACCESS_TOKEN" == "null" ]; then
64+ echo "Error: Failed to authenticate with BlueSky"
65+ echo "Response: $AUTH_RESPONSE"
66+ exit 1
67+ fi
68+
69+ echo "✓ Authenticated as $DID"
70+
71+ # Create post text
72+ POST_TEXT="🚀 Open in Notepad++ v${VERSION} for #VisualStudio has been released!"
73+ POST_TEXT="${POST_TEXT}"$'\n\n'"Check out the release notes here!"
74+ POST_TEXT="${POST_TEXT}"$'\n\n'"Marketplace: ${MARKETPLACE_URL}"
75+
76+ echo "Post text: $POST_TEXT"
77+
78+ # Get current timestamp in ISO 8601 format
79+ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
80+
81+ # Calculate facets (byte positions for hashtags and links)
82+ echo "Calculating facets for links and hashtags..."
83+ export POST_TEXT
84+ export RELEASE_URL
85+ FACETS=$(python3 -c "
86+ import json, re, os
87+ text = os.environ['POST_TEXT']
88+ release_url = os.environ['RELEASE_URL']
89+ facets = []
90+ # Add hashtag facets
91+ for m in re.finditer(r'#(\w+)', text):
92+ facets.append({
93+ 'index': {'byteStart': len(text[:m.start()].encode('utf-8')), 'byteEnd': len(text[:m.start()+len(m.group(0))].encode('utf-8'))},
94+ 'features': [{'\$type': 'app.bsky.richtext.facet#tag', 'tag': m.group(1)}]
95+ })
96+ # Add link facets for URLs
97+ for m in re.finditer(r'https?://[^\s]+', text):
98+ facets.append({
99+ 'index': {'byteStart': len(text[:m.start()].encode('utf-8')), 'byteEnd': len(text[:m.start()+len(m.group())].encode('utf-8'))},
100+ 'features': [{'\$type': 'app.bsky.richtext.facet#link', 'uri': m.group()}]
101+ })
102+ # Add link facet for 'Check out the release notes here!'
103+ release_text = 'Check out the release notes here!'
104+ idx = text.find(release_text)
105+ if idx >= 0:
106+ facets.append({
107+ 'index': {'byteStart': len(text[:idx].encode('utf-8')), 'byteEnd': len(text[:idx+len(release_text)].encode('utf-8'))},
108+ 'features': [{'\$type': 'app.bsky.richtext.facet#link', 'uri': release_url}]
109+ })
110+ print(json.dumps(facets))
111+ ")
112+
113+ echo "Facets: $FACETS"
114+
115+ # Create the post using jq to properly escape JSON
116+ echo "Creating BlueSky post..."
117+ POST_RESPONSE=$(jq -n \
118+ --arg did "$DID" \
119+ --arg text "$POST_TEXT" \
120+ --arg timestamp "$TIMESTAMP" \
121+ --argjson facets "$FACETS" \
122+ '{
123+ repo: $did,
124+ collection: "app.bsky.feed.post",
125+ record: {
126+ text: $text,
127+ facets: $facets,
128+ createdAt: $timestamp,
129+ "$type": "app.bsky.feed.post"
130+ }
131+ }' | curl -s -X POST https://bsky.social/xrpc/com.atproto.repo.createRecord \
132+ -H "Content-Type: application/json" \
133+ -H "Authorization: Bearer $ACCESS_TOKEN" \
134+ -d @-)
135+
136+ POST_URI=$(echo "$POST_RESPONSE" | jq -r '.uri')
137+
138+ if [ -z "$POST_URI" ] || [ "$POST_URI" == "null" ]; then
139+ echo "Error: Failed to create BlueSky post"
140+ echo "Response: $POST_RESPONSE"
141+ exit 1
142+ fi
143+
144+ # Extract the post ID from the URI
145+ POST_ID=$(echo "$POST_URI" | sed 's|.*/||')
146+ POST_URL="https://bsky.app/profile/${{ secrets.BLUESKY_USERNAME }}/post/$POST_ID"
147+
148+ echo "✓ Posted to BlueSky: $POST_URL"
149+ shell : bash
0 commit comments