diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 52b706a..742e2bc 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -29,15 +29,15 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v8.1.0 + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v9.0.0 with: enable-cache: false - name: Generate site run: uv run tools/generate_site.py --scripts-json scripts.json --assets-dir ASSETS --output-dir site - name: Upload Pages artifact if: github.event_name != 'pull_request' - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v5 with: path: ./site - name: Upload PR preview artifact @@ -56,4 +56,4 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment - uses: actions/deploy-pages@v4 + uses: actions/deploy-pages@v5 diff --git a/.github/workflows/localize-images.yml b/.github/workflows/localize-images.yml new file mode 100644 index 0000000..3de09de --- /dev/null +++ b/.github/workflows/localize-images.yml @@ -0,0 +1,59 @@ +name: Localize External Images + +on: + pull_request: + types: [labeled] + +permissions: + contents: write + +jobs: + localize-images: + # Only run when a maintainer applies the trigger label, and only for + # same-repo branches — GITHUB_TOKEN can never push to a fork's branch + # anyway, so skip the attempt rather than fail noisily. + if: | + github.event.label.name == 'localize-images' && + github.event.pull_request.head.repo.full_name == github.repository + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v7 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - uses: astral-sh/setup-uv@v9.0.0 + with: + enable-cache: false + + - name: Configure git identity + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Download and localize external images + run: | + set +e + uv run tools/download_external_images.py 2>&1 | tee /tmp/localize-images-output.txt + exit_code=${PIPESTATUS[0]} + set -e + if [ "$exit_code" -eq 2 ]; then + echo "::error::download_external_images.py failed with a file I/O or argument error — see the log above." + exit 2 + fi + if [ "$exit_code" -eq 1 ]; then + echo "::warning::Some images failed to download — see the log above. Any entries that succeeded were still applied." + fi + + # Downloaded images are new, untracked files under ASSETS/, not just + # modifications to scripts.json — stage first so `git diff --cached` + # picks those up too, then only commit if something actually changed. + - name: Commit localized images if anything changed + run: | + git add scripts.json ASSETS + if git diff --cached --quiet; then + echo "No image changes to commit." + else + git commit -m "chore: localize external images" + git push origin "HEAD:${{ github.event.pull_request.head.ref }}" + fi diff --git a/.github/workflows/script-submission.yml b/.github/workflows/script-submission.yml index 53b6ec9..0e804f3 100644 --- a/.github/workflows/script-submission.yml +++ b/.github/workflows/script-submission.yml @@ -18,9 +18,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v7 - - uses: astral-sh/setup-uv@v8.1.0 + - uses: astral-sh/setup-uv@v9.0.0 with: enable-cache: false @@ -71,9 +71,10 @@ jobs: .github/ISSUE_TEMPLATE/update-script.yml VERB="Add" if [ "$MODE" = "patch" ]; then VERB="Update"; fi + CLEAN_TITLE=$(echo "$ISSUE_TITLE" | sed -E 's/^\[Lua App (Submission|Update)\] *//') git commit -m "feat(scripts): ${VERB} script from issue #${ISSUE_NUMBER} - ${ISSUE_TITLE} + ${CLEAN_TITLE} Closes #${ISSUE_NUMBER}" git push origin "$BRANCH" @@ -94,11 +95,12 @@ jobs: const mode = process.env.MODE; const verb = mode === "insert" ? "Add" : "Update"; + const cleanTitle = issueTitle.replace(/^\[Lua App (?:Submission|Update)\]\s*/, ""); const pr = await github.rest.pulls.create({ owner: context.repo.owner, repo: context.repo.repo, - title: `feat(scripts): ${verb} script — ${issueTitle}`, + title: `feat(scripts): ${verb} ${cleanTitle}`, head: branch, base: "main", draft: true, @@ -107,7 +109,7 @@ jobs: "", "### Checklist before merging", "- [ ] Verify the `scripts.json` diff looks correct", - "- [ ] If any images are still external URLs, run `uv run tools/download_external_images.py` to pull them into `ASSETS/` and update `scripts.json` automatically (use `--dry-run` to preview first)", + "- [ ] If any images are still external URLs, add the `localize-images` label to this PR to pull them into `ASSETS/` and update `scripts.json` automatically (or run `uv run tools/download_external_images.py` locally, using `--dry-run` to preview first)", "- [ ] Remove draft status when ready to merge", "", `Closes #${issueNumber}` diff --git a/.github/workflows/validate-issue-templates.yml b/.github/workflows/validate-issue-templates.yml index 2dc7fd9..5334f1c 100644 --- a/.github/workflows/validate-issue-templates.yml +++ b/.github/workflows/validate-issue-templates.yml @@ -40,8 +40,8 @@ jobs: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v8.1.0 + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v9.0.0 with: enable-cache: false - name: Run sync script tests @@ -59,8 +59,8 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v8.1.0 + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v9.0.0 with: enable-cache: false - name: Run sync script tests @@ -104,8 +104,8 @@ jobs: # trusted copy of the sync script, never the PR's own version — a # malicious PR can't smuggle in a modified script for this elevated # job to execute. - - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v8.1.0 + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v9.0.0 with: enable-cache: false - name: Fetch PR's scripts.json as data only (never executed) diff --git a/.github/workflows/validate-scripts-json.yml b/.github/workflows/validate-scripts-json.yml index 56fe32a..85f8ff6 100644 --- a/.github/workflows/validate-scripts-json.yml +++ b/.github/workflows/validate-scripts-json.yml @@ -17,8 +17,8 @@ jobs: validate: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: astral-sh/setup-uv@v8.1.0 + - uses: actions/checkout@v7 + - uses: astral-sh/setup-uv@v9.0.0 with: enable-cache: false - name: Validate scripts.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..0886deb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,49 @@ +# Contributing + +This repo is a gallery of community Lua Apps and Widgets for EdgeTX. [`scripts.json`](scripts.json) is the +single source of content — entries are validated against [`scripts.schema.json`](scripts.schema.json) and +rendered into the [gallery site](https://edgetx.org/lua-scripts/). + +## Submitting or updating a gallery entry + +You don't need to edit `scripts.json` yourself — open an issue instead: + +- [Add a Lua App or Widget to the Gallery](https://github.com/EdgeTX/lua-scripts/issues/new?template=add-script.yml) +- [Update / Correct a Lua App or Widget Entry](https://github.com/EdgeTX/lua-scripts/issues/new?template=update-script.yml) +- [Feedback / Report an Issue](https://github.com/EdgeTX/lua-scripts/issues/new?template=feedback.yml) + +Fill in the form fields — name, category, description, info URL, and (optionally) screenshots. Screenshot URLs +can be external links (raw GitHub, Imgur, etc.) or you can drag-and-drop / paste image files directly into the +form and GitHub will host them for you. + +## What happens after you submit + +1. A maintainer reviews the issue and applies the `add-to-gallery` (new entry) or `update-in-gallery` + (existing entry) label. +2. That label triggers [`script-submission.yml`](.github/workflows/script-submission.yml), which parses the + issue, updates `scripts.json`, validates it, and opens a **draft PR** back to the issue. +3. If the submission included external image URLs, a maintainer applies the `localize-images` label to the + draft PR. This triggers [`localize-images.yml`](.github/workflows/localize-images.yml), which downloads + those images into `ASSETS//`, rewrites `scripts.json` to point at the local copies, and pushes the + result back to the PR branch as a commit. +4. Once the diff looks correct, a maintainer removes draft status and merges. +5. Merging to `main` regenerates the gallery site via [`gh-pages.yml`](.github/workflows/gh-pages.yml). + +## CI checks + +- [`validate-scripts-json.yml`](.github/workflows/validate-scripts-json.yml) validates `scripts.json` against + `scripts.schema.json` on every push/PR that touches it. +- [`validate-issue-templates.yml`](.github/workflows/validate-issue-templates.yml) keeps the tag/category + dropdowns in the issue templates in sync with `scripts.schema.json`, and self-heals same-repo branches + automatically when they drift. + +## Running the tooling locally + +The scripts under [`tools/`](tools/) are plain Python, run via [`uv`](https://docs.astral.sh/uv/) — no project +setup required beyond having `uv` installed: + +```bash +uv run tools/validate_scripts.py --scripts-json scripts.json +uv run tools/download_external_images.py --dry-run # preview image localization +uv run tools/sync_issue_template_options.py --check # check tag/category drift +```