diff --git a/.github/workflows/validate-apps.yml b/.github/workflows/validate-apps.yml new file mode 100644 index 000000000..fb0c7a321 --- /dev/null +++ b/.github/workflows/validate-apps.yml @@ -0,0 +1,101 @@ +name: Validate app files + +on: + pull_request: + paths: + - 'apps/**' + +permissions: + contents: read + pull-requests: write + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Get modified app files + id: changed + run: | + FILES=$(git diff --name-only --diff-filter=ACMR ${{ github.event.pull_request.base.sha }}...HEAD -- 'apps/*' | grep -v '\.template$' || true) + echo "files<> $GITHUB_OUTPUT + echo "$FILES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Download pla-site-tool + if: steps.changed.outputs.files != '' + run: | + wget -q -O pla-site-tool "$(curl -Ls https://api.github.com/repos/kazam0180/portable-apps/releases | sed 's/[()",{} ]/\n/g' | grep -oi "https.*pla-site-tool.*mage$" | head -1)" + chmod +x pla-site-tool + + - name: Validate files + if: steps.changed.outputs.files != '' + id: validate + run: | + FAILED="" + while IFS= read -r file; do + [ -z "$file" ] && continue + echo "Validating: $file" + set +e + OUTPUT=$(./pla-site-tool -i "$file" 2>&1) + EXIT_CODE=$? + set -e + echo "$OUTPUT" + if [ $EXIT_CODE -ne 0 ] || [ ! -s "${file}.json" ] || ! python3 -c "import json; json.load(open('${file}.json'))" 2>/dev/null; then + echo "FAILED: $file" + FAILED="${FAILED}${file}\n" + else + rm -f "${file}.json" + fi + done <<< "${{ steps.changed.outputs.files }}" + + if [ -n "$FAILED" ]; then + echo "failed<> $GITHUB_OUTPUT + echo -e "$FAILED" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + echo "has_failed=true" >> $GITHUB_OUTPUT + else + echo "has_failed=false" >> $GITHUB_OUTPUT + fi + + - name: Comment on PR + if: steps.validate.outputs.has_failed == 'true' + uses: actions/github-script@v7 + with: + script: | + const failedFiles = `${{ steps.validate.outputs.failed }}`.trim().split('\n').filter(f => f); + const body = `### App file validation failed\n\nThe following files could not be converted to JSON:\n\n${failedFiles.map(f => `- \`${f}\``).join('\n')}\n\nPlease check the file format against [\`apps/.template\`](https://github.com/Portable-Linux-Apps/Portable-Linux-Apps.github.io/blob/main/apps/.template) and fix any syntax errors.`; + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + + const botComment = comments.find(c => c.user.type === 'Bot' && c.body.includes('App file validation failed')); + + if (botComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + } + + - name: Fail if validation errors + if: steps.validate.outputs.has_failed == 'true' + run: | + echo "Validation failed for the files listed in the PR comment." + exit 1 diff --git a/apps/anotherapp b/apps/anotherapp new file mode 100644 index 000000000..2cd080f66 --- /dev/null +++ b/apps/anotherapp @@ -0,0 +1 @@ +# new app diff --git a/apps/anotherotherapp b/apps/anotherotherapp new file mode 100644 index 000000000..46518acfb --- /dev/null +++ b/apps/anotherotherapp @@ -0,0 +1,13 @@ +# some app + +=== +description of your app. must be within the `===` lines. +only use **bold**, *italic*, ++underline++, lists markdown here +- do not add links or images here +- use SOURCES field if you package someone else's app +=== + +# SCREENSHOTS: https://Portable-Linux-Apps.github.io/contribute_ss.webp +# SITES: https://someapp.io +# SOURCES: https://github.com/name/someapp-appimage +# BUTTONS: Label_of_Button::https://discord.gg Donation_Link::https://someapp.io/donate diff --git a/apps/testappp b/apps/testappp new file mode 100644 index 000000000..57106caac --- /dev/null +++ b/apps/testappp @@ -0,0 +1 @@ +new app