Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions .github/workflows/deploy-website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,26 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v6


- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: bun install --frozen-lockfile
working-directory: website

- name: Build website
run: bun run build
working-directory: website

- name: Setup Pages
uses: actions/configure-pages@v5

- name: Upload artifact
uses: actions/upload-pages-artifact@v4
with:
# Upload the website directory
path: './website'

path: './website/dist'

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
97 changes: 87 additions & 10 deletions .github/workflows/publish-website-artifacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,40 +41,117 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Copy artifacts to website folder
- name: Copy artifacts to website public folder
run: |
mkdir -p website
mkdir -p website/public

# Copy macOS DMG
DMG_FILE=$(find /tmp/artifacts -name "*.dmg" | head -1)
if [ -n "$DMG_FILE" ]; then
cp "$DMG_FILE" website/astro-editor-latest.dmg
cp "$DMG_FILE" website/public/astro-editor-latest.dmg
echo "Copied DMG: $DMG_FILE"
fi

# Copy Windows MSI
MSI_FILE=$(find /tmp/artifacts -name "*.msi" | head -1)
if [ -n "$MSI_FILE" ]; then
cp "$MSI_FILE" website/astro-editor-latest.msi
cp "$MSI_FILE" website/public/astro-editor-latest.msi
echo "Copied MSI: $MSI_FILE"
fi

# Copy Linux AppImage
APPIMAGE_FILE=$(find /tmp/artifacts -name "*.AppImage" | head -1)
if [ -n "$APPIMAGE_FILE" ]; then
cp "$APPIMAGE_FILE" website/astro-editor-latest.AppImage
cp "$APPIMAGE_FILE" website/public/astro-editor-latest.AppImage
echo "Copied AppImage: $APPIMAGE_FILE"
fi

echo "Website folder contents:"
ls -la website/*.dmg website/*.msi website/*.AppImage 2>/dev/null || true
echo "Website public folder contents:"
ls -la website/public/*.dmg website/public/*.msi website/public/*.AppImage 2>/dev/null || true
Comment thread
dannysmith marked this conversation as resolved.

- name: Commit website artifacts
- name: Generate release page
run: |
RELEASE_BODY=$(gh release view "$RELEASE_TAG" --json body -q .body)
VERSION="${RELEASE_TAG#v}"
DATE=$(gh release view "$RELEASE_TAG" --json publishedAt -q .publishedAt | cut -dT -f1)

# Sanitise body for MDX:
# - Strip leading H2 title
# - Strip "Installation Instructions" section and everything after
# - Strip "Full Changelog" links
# - Escape curly braces outside code spans/blocks
#
# NOTE: This logic is duplicated in website/scripts/generate-release-pages.ts
# (sanitiseBody, escapeCurlyBraces, localiseImages). If you change this,
# update that script too (and vice versa).
CLEAN_BODY=$(printf '%s\n' "$RELEASE_BODY" | \
sed '/^## *\(🚀 *\)\{0,1\}Astro Editor v[0-9]/d' | \
sed '/^### Installation Instructions/,$d' | \
sed '/^\*\*Full Changelog\*\*/d' | \
Comment thread
dannysmith marked this conversation as resolved.
awk '
/^```/ { in_code = !in_code }
in_code { print; next }
{
line = ""
n = split($0, chars, "")
in_tick = 0
for (i = 1; i <= n; i++) {
if (chars[i] == "`") in_tick = !in_tick
if (!in_tick && chars[i] == "{") { line = line "" "&#123;"; continue }
if (!in_tick && chars[i] == "}") { line = line "" "&#125;"; continue }
line = line chars[i]
}
print line
}
' | \
sed -e :a -e '/^[[:space:]]*$/{ $d; N; ba; }')

# Download GitHub attachment images to local repo
IMAGES_DIR="website/public/releases"
mkdir -p "$IMAGES_DIR"
IMAGE_URLS=$(printf '%s\n' "$CLEAN_BODY" | grep -oE 'https://github\.com/user-attachments/assets/[a-f0-9-]+' | sort -u || true)
IMG_INDEX=0
for URL in $IMAGE_URLS; do
IMG_INDEX=$((IMG_INDEX + 1))
LOCAL_NAME="${VERSION}-${IMG_INDEX}.png"
curl -sL -o "${IMAGES_DIR}/${LOCAL_NAME}" "$URL"
CLEAN_BODY=$(printf '%s' "$CLEAN_BODY" | sed "s|${URL}|/releases/${LOCAL_NAME}|g")
echo "Downloaded image: ${LOCAL_NAME}"
done
Comment on lines +114 to +120

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential issue with sed substitution when URL contains special characters.

The sed command uses | as a delimiter, but if $URL or $LOCAL_NAME contain pipe characters or other regex metacharacters, the substitution will fail or produce unexpected results.

Consider using a safer approach:

Proposed fix using awk or printf escaping
           for URL in $IMAGE_URLS; do
             IMG_INDEX=$((IMG_INDEX + 1))
             LOCAL_NAME="${VERSION}-${IMG_INDEX}.png"
             curl -sL -o "${IMAGES_DIR}/${LOCAL_NAME}" "$URL"
-            CLEAN_BODY=$(printf '%s' "$CLEAN_BODY" | sed "s|${URL}|/releases/${LOCAL_NAME}|g")
+            CLEAN_BODY="${CLEAN_BODY//"$URL"/"/releases/${LOCAL_NAME}"}"
             echo "Downloaded image: ${LOCAL_NAME}"
           done
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-website-artifacts.yml around lines 110 - 116, The
sed substitution on CLEAN_BODY using the raw $URL and $LOCAL_NAME is unsafe when
those values contain regex metacharacters or the chosen delimiter; create and
use escaped versions (e.g., ESC_URL and ESC_LOCAL_NAME) that backslash-escape
sed-special characters (delimiter, /, &, |, etc.) before calling sed, or replace
the sed step with a literal-safe tool (awk or parameter expansion) that performs
a literal string replacement; update the loop to compute ESC_URL and
ESC_LOCAL_NAME from URL and LOCAL_NAME and use those escaped names in the sed
substitution that updates CLEAN_BODY.


# Generate MDX file
RELEASES_DIR="website/src/content/docs/releases"
mkdir -p "$RELEASES_DIR"
OUTPUT_FILE="$RELEASES_DIR/${VERSION}.mdx"

{
printf '%s\n' "---"
printf '%s\n' "title: 'v${VERSION}'"
printf '%s\n' "description: 'Astro Editor v${VERSION}'"
printf '%s\n' "date: ${DATE}"
printf '%s\n' "slug: 'releases/v${VERSION}'"
printf '%s\n' "---"

if [ -n "$CLEAN_BODY" ]; then
printf '\n%s\n\n%s\n' "$CLEAN_BODY" "---"
fi

printf '\n%s\n' "[View on GitHub](https://github.com/dannysmith/astro-editor/releases/tag/${RELEASE_TAG})"
} > "$OUTPUT_FILE"

echo "Generated release page: $OUTPUT_FILE"
cat "$OUTPUT_FILE"
Comment on lines +72 to +143

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Duplicated sanitization logic diverges from the TypeScript implementation.

This inline bash reimplements the release page generation logic that already exists in website/scripts/generate-release-pages.ts. The implementations have subtle differences that may produce inconsistent results:

  1. Full Changelog stripping (line 86): Bash uses /^\*\*Full Changelog\*\*/d which only matches lines starting with **Full Changelog**, while TypeScript uses /\*\*Full Changelog\*\*:.*$/gm which matches anywhere and requires the colon.

  2. Curly brace escaping (lines 87-101): The bash awk tracks single backticks character-by-character, but doesn't handle multi-backtick delimiters like `` `code` `` that the TypeScript version supports via regex splitting.

  3. H2 title stripping (line 84): Minor regex differences in whitespace handling.

Consider invoking the TypeScript script directly instead of maintaining parallel implementations:

🔧 Suggested approach: Use the existing script
       - name: Generate release page
         run: |
-          RELEASE_BODY=$(gh release view "$RELEASE_TAG" --json body -q .body)
-          # ... 60+ lines of bash sanitization ...
+          cd website
+          npx tsx scripts/generate-release-pages.ts --all
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

This requires setting up Node/Bun in an earlier step, but ensures consistent behavior between manual and automated generation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-website-artifacts.yml around lines 72 - 139, The
bash step duplicates and diverges from the existing TypeScript logic; instead of
the CLEAN_BODY sanitization, call the existing script
(website/scripts/generate-release-pages.ts) to generate the MDX so behavior
(Full Changelog stripping, curly-brace escaping, H2 stripping) remains
consistent—add a prior step to install Node/Bun runtime, then invoke the TS
script with RELEASE_TAG (and/or output dir) so IMAGES_DIR/IMAGE_URLS handling
and output file creation are handled by the single canonical implementation;
remove the inline awk/sed sanitization and the image-download loop from this
job.

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Commit website artifacts and release page
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add website/astro-editor-latest.dmg website/astro-editor-latest.msi website/astro-editor-latest.AppImage 2>/dev/null || true
git commit -m "chore: update installers for $RELEASE_TAG" || echo "No changes to commit"
git add website/public/astro-editor-latest.dmg website/public/astro-editor-latest.msi website/public/astro-editor-latest.AppImage 2>/dev/null || true
git add website/public/releases/*.png 2>/dev/null || true
git add website/src/content/docs/releases/*.mdx 2>/dev/null || true
git commit -m "chore: update installers and add release page for $RELEASE_TAG" || echo "No changes to commit"
git pull --rebase origin main
git push origin main

Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,9 @@ temp-dummy-astro-project/
# Code quality reports
jscpd-report/

.claude/worktrees/
# Website build artifacts
website/dist/
website/.astro/
website/node_modules/

.claude/worktrees/
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"css": "css"
},
"files.associations": {
"*.css": "tailwindcss"
"*.css": "tailwindcss",
"*.mdx": "markdown"
}
}
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
- Comprehensive keyboard shortcuts and menu integration
- Toast notifications throughout the app

**Note:** The `website/` directory is an independent project that uses **bun** (not pnpm). It is not part of the pnpm workspace. See `website/AGENTS.md` for its own instructions.

## Core Rules

### New Sessions
Expand Down
Loading
Loading