Skip to content

Commit 38a3ea6

Browse files
authored
replace Imgur with GitHub Release Assets for screenshot hosting (#3573)
* replace Imgur with GitHub Release Assets for screenshot hosting Fixes #3548 ## Problem Imgur API returns "Too Many Requests" errors (code 1025), blocking successfully tested applications from being merged. ## Solution Replace Imgur with GitHub Release Assets: - Screenshots are uploaded to a draft release named 'ci-screenshots' - Inline images displayed in PR comments - Works for PRs from external contributors using workflow_run trigger * sanitize filenames for artifact upload - Add step to sanitize screenshot filenames before upload - Remove invalid characters (: * ? < > |) from app names - Fixes error with apps like 'fre:ac' containing colons - Update publish workflow to handle flat file structure * ci: fix artifact path and publish release; guard workflow to upstream repo
1 parent 4b07f2e commit 38a3ea6

File tree

3 files changed

+129
-7
lines changed

3 files changed

+129
-7
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Publish PR Screenshot
2+
3+
on:
4+
workflow_run:
5+
workflows: ["Test"]
6+
types: [completed]
7+
8+
jobs:
9+
publish:
10+
if: >
11+
github.event.workflow_run.conclusion == 'success' &&
12+
github.event.workflow_run.event == 'pull_request' &&
13+
github.repository == 'AppImage/appimage.github.io'
14+
runs-on: ubuntu-latest
15+
permissions:
16+
actions: read
17+
contents: write
18+
pull-requests: write
19+
env:
20+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21+
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@v3
25+
26+
- name: Extract PR number from event
27+
id: extract-pr
28+
shell: bash
29+
run: |
30+
PR_NUMBER=$(jq -r '.workflow_run.pull_requests[0].number // empty' "$GITHUB_EVENT_PATH")
31+
echo "PR_NUMBER=${PR_NUMBER}" >> $GITHUB_ENV
32+
echo "PR_NUMBER=${PR_NUMBER}"
33+
echo "pr_number=${PR_NUMBER}" >> $GITHUB_OUTPUT
34+
- name: Download screenshot artifacts
35+
uses: dawidd6/action-download-artifact@v2
36+
with:
37+
run_id: ${{ github.event.workflow_run.id }}
38+
name: pr-screenshots
39+
path: ./out
40+
if_no_artifact_found: ignore
41+
42+
- name: Prepare files
43+
id: prep
44+
shell: bash
45+
run: |
46+
set -e
47+
mkdir -p upload
48+
: > upload/list.txt
49+
SHORT="${HEAD_SHA::8}"
50+
COUNT=0
51+
FALLBACK="run-${{ github.event.workflow_run.id }}"
52+
for f in out/*.png; do
53+
[ -f "$f" ] || continue
54+
base="$(basename "$f")"
55+
appname="${base%.png}" # Remove .png extension to get app name
56+
# Produce deterministic upload name with app name
57+
PN="${PR_NUMBER:-$FALLBACK}"
58+
name="pr-${PN}-${SHORT}-${appname}.png"
59+
cp "$f" "upload/${name}"
60+
echo "${name}" >> upload/list.txt
61+
COUNT=$((COUNT+1))
62+
done
63+
echo "COUNT=${COUNT}" >> $GITHUB_ENV
64+
echo "count=${COUNT}" >> $GITHUB_OUTPUT
65+
66+
- name: Ensure release exists (published)
67+
shell: bash
68+
run: |
69+
gh release view ci-screenshots >/dev/null 2>&1 || \
70+
gh release create ci-screenshots -t "CI Screenshots" -n "Automated screenshots from PRs" --prerelease
71+
gh release edit ci-screenshots --draft=false
72+
73+
- name: Upload assets
74+
if: ${{ steps.prep.outputs.count != '0' }}
75+
shell: bash
76+
run: |
77+
while IFS= read -r name; do
78+
gh release upload ci-screenshots "upload/${name}" --clobber
79+
done < upload/list.txt
80+
81+
- name: Comment on PR with images
82+
if: ${{ steps.prep.outputs.count != '0' && steps.extract-pr.outputs.pr_number != '' }}
83+
shell: bash
84+
run: |
85+
repo="${{ github.repository }}"
86+
{
87+
echo "Automated screenshot(s) for PR #${PR_NUMBER} (commit ${HEAD_SHA}):"
88+
echo ""
89+
while IFS= read -r name; do
90+
url="https://github.com/${repo}/releases/download/ci-screenshots/${name}"
91+
echo "![Screenshot](${url})"
92+
echo ""
93+
done < upload/list.txt
94+
} > comment.txt
95+
gh api "repos/${repo}/issues/${PR_NUMBER}/comments" -F [email protected]
96+

.github/workflows/test.yml

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
name: Test
2+
13
on:
24
push:
35
branches:
@@ -19,6 +21,7 @@ jobs:
1921
runs-on: ubuntu-22.04
2022
timeout-minutes: 10
2123
permissions:
24+
actions: write
2225
contents: write
2326
pull-requests: write
2427
steps:
@@ -46,6 +49,10 @@ jobs:
4649
sudo gem install dupervisor -v 1.0.5 # To convert ini to yaml files
4750
sudo npm install -g asar # to get pacakges.json from resources/app.asar for electron-builder applications
4851
# npm install -g @alexlafroscia/yaml-merge # to merge yaml files
52+
- name: Mark screenshot start (PR only)
53+
if: github.event_name == 'pull_request'
54+
run: |
55+
touch .screenshots_start
4956
- name: Main test
5057
# shell: bash
5158
run: |
@@ -83,6 +90,28 @@ jobs:
8390
# xpra stop :99
8491
killall Xvfb
8592
# bundle exec jekyll build # https://help.github.com/en/articles/viewing-jekyll-build-error-messages#configuring-a-third-party-service-to-display-jekyll-build-error-messages
93+
- name: Prepare screenshots for upload
94+
if: github.event_name == 'pull_request'
95+
shell: bash
96+
run: |
97+
mkdir -p screenshots-upload
98+
# only files modified during this run
99+
while IFS= read -r screenshot; do
100+
[ -f "$screenshot" ] || continue
101+
appname=$(basename "$(dirname "$screenshot")")
102+
# Sanitize filename: allow letters, digits, dot, underscore, hyphen
103+
safe_name=$(echo "$appname" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9._-')
104+
cp "$screenshot" "screenshots-upload/${safe_name}.png"
105+
done < <(find database -type f -path '*/screenshot.png' -newer .screenshots_start -print)
106+
ls -la screenshots-upload/ || true
107+
- name: Upload screenshot artifact
108+
if: github.event_name == 'pull_request'
109+
uses: actions/upload-artifact@v4
110+
with:
111+
name: pr-screenshots
112+
path: screenshots-upload/*.png
113+
if-no-files-found: ignore
114+
retention-days: 7
86115
- name: Check log
87116
if: github.event_name == 'pull_request' && github.event.pull_request.user.login == 'probonopd'
88117
shell: bash
@@ -91,13 +120,12 @@ jobs:
91120
grep -r "Running as root without --no-sandbox is not supported" log.txt && MESSAGE="Pending #2563 (\`Running as root without --no-sandbox is not supported\`)." && exit 1
92121
grep -r "version \`GLIBC_.*' not found" && MESSAGE="This was compiled on a too new system and hence cannot run on all still-supported versions of Ubuntu." && exit 1
93122
echo "${MESSAGE}"
94-
SCREENSHOT_URL=$(cat log.txt | grep -o -e "https://i.imgur.com.*.png") || true
95-
if [[ -z "${SCREENSHOT_URL}" ]]; then
96-
echo "No screenshot URL found."
123+
COUNT=$(ls database/*/screenshot.png 2>/dev/null | wc -l)
124+
if [[ "${COUNT}" -eq 0 ]]; then
125+
echo "No screenshot file found."
97126
exit 1
98127
fi
99-
echo "SCREENSHOT_URL=$SCREENSHOT_URL" >> $GITHUB_ENV || true
100-
echo "SCREENSHOT_URL: ${SCREENSHOT_URL}" || true
128+
echo "Found ${COUNT} screenshot file(s)."
101129
# The following is disabled because it gives errors about missing permissions
102130
# whenever a PR is made by anyone but the repo maintainer
103131
# - name: Post Screenshot URL

code/worker.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,8 +573,6 @@ if [ "$IS_PULLREQUEST" = true ]; then
573573
cat "apps/${INPUTBASENAME}.md" || exit 1
574574
cat "database/${INPUTBASENAME}/"*.desktop || exit 1 # Asterisk must not be inside quotes, https://travis-ci.org/AppImage/appimage.github.io/builds/360847207#L782
575575
ls -lh "database/${INPUTBASENAME}/screenshot.png" || exit 1
576-
wget -q https://raw.githubusercontent.com/tremby/imgur.sh/1c64feeefb6590741eb3d034575f9c788469b0a8/imgur.sh
577-
bash imgur.sh "database/${INPUTBASENAME}/screenshot.png"
578576
echo ""
579577
echo "We will assume the test is OK (a pull request event was triggered and the required files exist)."
580578
exit 0

0 commit comments

Comments
 (0)