Skip to content

Don't fail compare CI with insufficient permissions to comment #364

Don't fail compare CI with insufficient permissions to comment

Don't fail compare CI with insufficient permissions to comment #364

Workflow file for this run

name: build-site-and-compare
on:
push:
branches:
tags:
paths-ignore:
- 'publisher/**'
- 'updater/**'
- '.github/workflows/ci-build-publisher.yml'
- '.github/workflows/ci-build-updater.yml'
- '.github/workflows/ci-frontend-check.yml'
- '.github/workflows/ci-frontend-lint.yml'
- '.github/dependabot.yml'
- '.github/FUNDING.yml'
- 'hugo/content/**' # content likely won't break the build
pull_request:
paths-ignore:
- 'publisher/**'
- 'updater/**'
- '.github/workflows/ci-build-publisher.yml'
- '.github/workflows/ci-build-updater.yml'
- '.github/workflows/ci-frontend-check.yml'
- '.github/workflows/ci-frontend-lint.yml'
- '.github/dependabot.yml'
- '.github/FUNDING.yml'
- 'hugo/content/**' # content likely won't break the build
jobs:
build:
name: build-and-compare
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed to fetch all history for comparison
# for prettier as it's unknown how to build css and js without them being minimized
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22.x'
cache: 'npm'
cache-dependency-path: hugo
- name: Set directory names
id: set-dirs
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "old_dir=master" >> $GITHUB_OUTPUT
echo "new_dir=pr-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
else
echo "old_dir=old-master" >> $GITHUB_OUTPUT
echo "new_dir=new-master" >> $GITHUB_OUTPUT
fi
- name: Get comparison commit
id: get-comparison-commit
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "compare_sha=$(git rev-parse ${{ github.event.pull_request.base.sha }})" >> $GITHUB_OUTPUT
else
echo "compare_sha=$(git rev-parse HEAD^1)" >> $GITHUB_OUTPUT
fi
- name: Build previous version
run: |
git checkout ${{ steps.get-comparison-commit.outputs.compare_sha }}
docker build -t radio-t/site:previous --build-arg DO_NOT_MINIFY=true .
# Create directories for previous build
mkdir -p ${{ steps.set-dirs.outputs.old_dir }}/hugo
cp -r hugo/* ${{ steps.set-dirs.outputs.old_dir }}/hugo/
mkdir -p ${{ steps.set-dirs.outputs.old_dir }}/public
# Run the container with proper volume mounts
docker run --rm \
-v ${{ github.workspace }}/${{ steps.set-dirs.outputs.old_dir }}/hugo:/srv/hugo \
-v ${{ github.workspace }}/${{ steps.set-dirs.outputs.old_dir }}/public:/srv/hugo/public \
-e DO_NOT_MINIFY_HUGO=true \
radio-t/site:previous
# chown everything to the calling user as otherwise it's not possible to change it with sed and prettier later
sudo chown -R $USER:$USER ${{ steps.set-dirs.outputs.old_dir }}/public
- name: Build current version
run: |
git checkout ${{ github.event.pull_request.head.sha || github.sha }}
docker build -t radio-t/site:current --build-arg DO_NOT_MINIFY=true .
# Create directories for current build
mkdir -p ${{ steps.set-dirs.outputs.new_dir }}/hugo
cp -r hugo/* ${{ steps.set-dirs.outputs.new_dir }}/hugo/
mkdir -p ${{ steps.set-dirs.outputs.new_dir }}/public
# Run the container with proper volume mounts
docker run --rm \
-v ${{ github.workspace }}/${{ steps.set-dirs.outputs.new_dir }}/hugo:/srv/hugo \
-v ${{ github.workspace }}/${{ steps.set-dirs.outputs.new_dir }}/public:/srv/hugo/public \
-e DO_NOT_MINIFY_HUGO=true \
radio-t/site:current
# chown everything to the calling user as otherwise it's not possible to change it with sed and prettier later
sudo chown -R $USER:$USER ${{ steps.set-dirs.outputs.new_dir }}/public
- name: Install Prettier
run: npm install -g prettier
- name: Prettify CSS in public directories
run: |
prettier --write "${{ steps.set-dirs.outputs.old_dir }}/public/**/*.css"
prettier --write "${{ steps.set-dirs.outputs.new_dir }}/public/**/*.css"
- name: Remove itunes:subtitle from RSS feeds before comparison
run: |
sed -i 's#<itunes:subtitle>.*</itunes:subtitle>##' ${{ steps.set-dirs.outputs.old_dir }}/public/podcast-archives-short.rss
sed -i 's#<itunes:subtitle>.*</itunes:subtitle>##' ${{ steps.set-dirs.outputs.new_dir }}/public/podcast-archives-short.rss
sed -i 's#<itunes:subtitle>.*</itunes:subtitle>##' ${{ steps.set-dirs.outputs.old_dir }}/public/podcast-archives.rss
sed -i 's#<itunes:subtitle>.*</itunes:subtitle>##' ${{ steps.set-dirs.outputs.new_dir }}/public/podcast-archives.rss
- name: Remove hashes from CSS and JS files references
run: |
find ${{ steps.set-dirs.outputs.old_dir }}/public -type f -exec sed -i 's/\(js\|css\)?id=[^"'\''"]\+/\1/g' {} +
find ${{ steps.set-dirs.outputs.new_dir }}/public -type f -exec sed -i 's/\(js\|css\)?id=[^"'\''"]\+/\1/g' {} +
- name: Generate diff
run: |
# Generate initial diff
diff -r -N -u ${{ steps.set-dirs.outputs.old_dir }}/public ${{ steps.set-dirs.outputs.new_dir }}/public > temp.diff || true
# Process diff file to adjust paths
sed -E 's#^(---|\+\+\+) (.+)/public/#\1 \2/#' temp.diff > changes.diff
# Store diff size for later use
diff_size=$(wc -c < changes.diff)
echo "diff_size=$diff_size" >> $GITHUB_ENV
# Delete changes.diff if it's empty
if [ ! -s changes.diff ]; then
rm changes.diff
fi
# Generate a summary of changed files
find ${{ steps.set-dirs.outputs.new_dir }}/public -type f -exec sh -c '
old_dir="${{ steps.set-dirs.outputs.old_dir }}"
new_dir="${{ steps.set-dirs.outputs.new_dir }}"
file_path=${1#$new_dir/public/}
prev_file="$old_dir/public/$file_path"
if [ ! -f "$prev_file" ]; then
echo "- New: \`$file_path\`"
elif ! cmp -s "$1" "$prev_file"; then
echo "- Modified: \`$file_path\`"
fi
' sh {} \; >> changes.md
# add line in the beginning of the file only if it's not empty
if [ -s changes.md ]; then
sed -i '1s/^/Changed files:\n\n/' changes.md
fi
find ${{ steps.set-dirs.outputs.old_dir }}/public -type f -exec sh -c '
old_dir="${{ steps.set-dirs.outputs.old_dir }}"
new_dir="${{ steps.set-dirs.outputs.new_dir }}"
file_path=${1#$old_dir/public/}
current_file="$new_dir/public/$file_path"
if [ ! -f "$current_file" ]; then
echo "- Deleted: \`$file_path\`"
fi
' sh {} \; >> changes.md
# delete summary if it's empty
if [ ! -s changes.md ]; then
rm changes.md
fi
- name: Create Pastebin Paste with the diff in case it's too large
if: github.event_name == 'pull_request' && env.diff_size >= 20000
env:
PASTEBIN_API_KEY: ${{ secrets.PASTEBIN_API_KEY }}
id: create-pastebin
run: |
# Use a URL-encoded paste name to handle special characters
paste_name=$(echo "radio-t.com Site Changes for PR #${{ github.event.pull_request.number }}, commit ${{ github.sha }}" | jq -sRr @uri)
# Post the diff file directly from changes.diff
# https://pastebin.com/doc_api
paste_output=$(curl --silent "https://pastebin.com/api/api_post.php" \
-d "api_dev_key=$PASTEBIN_API_KEY" \
-d "api_option=paste" \
-d "api_paste_expire_date=1M" \
-d "api_paste_format=diff" \
-d "api_paste_private=0" \
-d "api_paste_name=${paste_name}" \
-d "api_paste_code=$(< changes.diff)" || echo "curl call to pastebin failed")
# Check if the output is a valid URL, otherwise print an error
if [[ "$paste_output" == "https://"* ]]; then
echo "PASTE_URL=$paste_output" >> $GITHUB_ENV
else
echo "Error: Failed to create Pastebin paste: $paste_output" >&2
fi
- name: Upload changes.diff as artifact
uses: actions/upload-artifact@v4
with:
name: changes.diff
path: changes.diff
if-no-files-found: ignore
- name: Upload changes.md as artifact
uses: actions/upload-artifact@v4
with:
name: changes.md
path: changes.md
if-no-files-found: ignore
- name: Generate comment body in case there are changes
if: env.diff_size != 0
id: get-comment-body
run: |
SUMMARY=$(cat changes.md)
# Truncate SUMMARY if it exceeds 20,000 characters
if [ ${#SUMMARY} -gt 20000 ]; then
SUMMARY="${SUMMARY:0:20000}... (truncated)"
fi
echo "body<<EOF" >> $GITHUB_OUTPUT
echo "### Site Build Comparison" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "**Build completed at:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "\`\`\`" >> $GITHUB_OUTPUT
echo "$SUMMARY" >> $GITHUB_OUTPUT
echo "\`\`\`" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
# If diff is small enough (<20KB), include it directly under spoiler
if [ "$diff_size" -lt 20000 ]; then
echo "**Full changes:**" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "<details>" >> $GITHUB_OUTPUT
echo "<summary>Click to expand diff</summary>" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "\`\`\`diff" >> $GITHUB_OUTPUT
cat changes.diff >> $GITHUB_OUTPUT
echo "\`\`\`" >> $GITHUB_OUTPUT
echo "</details>" >> $GITHUB_OUTPUT
fi
echo "" >> $GITHUB_OUTPUT
echo "[View full changes diff](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})" >> $GITHUB_OUTPUT
if [ -n "$PASTE_URL" ]; then
echo "[View diff on Pastebin]($PASTE_URL)" >> $GITHUB_OUTPUT
fi
echo "EOF" >> $GITHUB_OUTPUT
- name: Generate comment body in case there are no changes
if: env.diff_size == 0
id: get-comment-body-no-changes
run: |
echo "body<<EOF" >> $GITHUB_OUTPUT
echo "### Site Build Comparison" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "**Build completed at:** $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "No changes detected." >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Find existing comment
id: find-comment
if: github.event_name == 'pull_request'
uses: peter-evans/find-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
body-includes: "### Site Build Comparison"
- name: Create or update comment
if: github.event_name == 'pull_request'
uses: peter-evans/create-or-update-comment@v4
continue-on-error: true
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: ${{ steps.get-comment-body.outputs.body }}${{ steps.get-comment-body-no-changes.outputs.body }}
edit-mode: replace