Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
121 changes: 121 additions & 0 deletions .github/workflows/update-merlin-sha256.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: Update Merlin SHA256 Checksums

on:
schedule:
# Every 15 minutes, offset from the top of the hour to reduce scheduler congestion.
- cron: '7,22,37,52 * * * *'
workflow_dispatch:

permissions:
contents: write

concurrency:
group: update-merlin-sha256
cancel-in-progress: false

jobs:
scrape-and-commit:
runs-on: ubuntu-latest
timeout-minutes: 5

steps:
- name: Checkout repository
uses: actions/checkout@v7
with:
ssh-key: ${{ secrets.DEPLOY_KEY }}

- name: Fetch, parse, and validate SHA256 signatures
shell: bash
run: |
set -euo pipefail

readonly SOURCE_URL='https://www.asuswrt-merlin.net/download'
readonly TARGET_FILE='merlin-sha256.txt'
readonly MIN_EXPECTED_ENTRIES=5

page_file="$(mktemp)"
candidate_file="$(mktemp)"
trap 'rm -f "$page_file" "$candidate_file"' EXIT

echo "Fetching SHA256 signatures from ${SOURCE_URL}..."
curl --fail --location --silent --show-error \
--retry 4 --retry-delay 5 --retry-connrefused \
--connect-timeout 15 --max-time 60 \
--user-agent 'MerlinAutoUpdate checksum mirror (+https://github.com/ExtremeFiretop/MerlinAutoUpdate-Router)' \
--output "$page_file" \
"$SOURCE_URL"

# Keep the same source section MerlinAU consumes today, but write to a
# temporary candidate so a scrape/parser failure cannot destroy the
# last-known-good mirror in the repository.
sed -n '/<.*>SHA256 signatures:<\/.*>/,/<\/pre>/p' "$page_file" | \
sed -n '/<pre[^>]*>/,/<\/pre>/p' | \
sed -e 's/^.*<pre[^>]*>//' \
-e 's/<[^>]*>//g' \
-e 's/^[[:space:]]*//' \
-e 's/[[:space:]]*$//' | \
tr -d '\r' | \
sed '/^[[:space:]]*$/d' > "$candidate_file"

echo "Validating candidate checksum list..."
awk -v min_entries="$MIN_EXPECTED_ENTRIES" '
BEGIN {
valid = 1
count = 0
}
{
count++

if (NF != 2) {
printf "Invalid field count on line %d: %s\n", NR, $0 > "/dev/stderr"
valid = 0
next
}

if (length($1) != 64 || $1 ~ /[^0-9A-Fa-f]/) {
printf "Invalid SHA256 on line %d: %s\n", NR, $1 > "/dev/stderr"
valid = 0
}

if (seen[$2]++) {
printf "Duplicate firmware filename on line %d: %s\n", NR, $2 > "/dev/stderr"
valid = 0
}
}
END {
if (count < min_entries) {
printf "Only %d checksum entries were parsed; expected at least %d.\n", count, min_entries > "/dev/stderr"
valid = 0
}

if (!valid)
exit 1
}
' "$candidate_file"

echo "Validated $(wc -l < "$candidate_file") checksum entries."
echo "Candidate preview:"
head -n 5 "$candidate_file"

# Replace the working-tree copy only after the candidate has passed
# every validation check. A failed run therefore leaves the repository
# and its last-known-good checksum mirror unchanged.
mv -f "$candidate_file" "$TARGET_FILE"

- name: Commit and push changes
shell: bash
run: |
set -euo pipefail

git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'

git add merlin-sha256.txt

if git diff --cached --quiet; then
echo 'No checksum changes detected. Nothing to commit.'
exit 0
fi

git commit -m 'Automated update: refresh Merlin SHA256 checksums'
git push
178 changes: 178 additions & 0 deletions ADDITIONAL_TERMS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# MerlinAU Additional Terms Under GNU GPLv3 Section 7

Effective date: [YYYY-MM-DD]

The MerlinAU software is licensed under the GNU General Public License
version 3.0 ("GPLv3").

This document contains additional terms authorized under Section 7 of
GPLv3 for MerlinAU material whose copyright holders have authorized
these terms.

These Additional Terms supplement, and do not replace, GPLv3.

Nothing in these Additional Terms is intended to restrict the rights to
run, study, copy, modify, or redistribute the software that are granted
under GPLv3.

## 1. Scope

These Additional Terms apply to MerlinAU material for which the
applicable copyright holder or copyright holders have authorized their
application.

They do not purport to impose additional terms on third-party material
for which the MerlinAU project does not have authority to impose such
terms.

Contributions accepted after the effective date of these Additional
Terms may be distributed subject to these Additional Terms where the
contributor has agreed to them.

## 2. Preservation of Attribution and Legal Notices

Pursuant to Section 7(b) of GPLv3, reasonable legal notices and author
attributions contained in covered MerlinAU material must be preserved.

This includes, where applicable, notices identifying:

- ExtremeFiretop as the original creator of the MerlinAU project;
- Martinski W. as an official co-author of the MerlinAU project;
- the applicable copyright notices;
- the GNU General Public License version 3.0;
- these Additional Terms; and
- the official MerlinAU project source.

The official MerlinAU project is:

https://github.com/ExtremeFiretop/MerlinAutoUpdate-Router

These requirements do not prevent a modified version from adding
appropriate attribution for its own authors and contributors.

## 3. Identification of Modified Versions

Pursuant to Section 7(c) of GPLv3, a version of covered MerlinAU
material that has been modified and conveyed to others must be
reasonably identified as different from the official MerlinAU version
from which it was derived.

A modified version must not misrepresent its origin or represent itself
as an unmodified official MerlinAU release.

Where reasonably visible to users, the modified version must identify
that:

1. it contains modifications to MerlinAU;
2. it is not an official MerlinAU release unless expressly authorized
as such by the MerlinAU project; and
3. the modifications were made by persons other than the maintainers of
the official MerlinAU release, where applicable.

This requirement supplements the modified-version notice requirements
already contained in Section 5 of GPLv3.

Nothing in this section prevents a derivative project from truthfully
describing itself as being based on, derived from, or forked from
MerlinAU.

## 4. No Misrepresentation of Origin

Pursuant to Section 7(c) of GPLv3, covered MerlinAU material may not be
conveyed in a manner that misrepresents the origin of that material.

A person distributing a modified version must not falsely state or
imply that the modifications:

- were created by the official MerlinAU project;
- were created by ExtremeFiretop;
- were created by Martinski W.;
- are maintained by the official MerlinAU project; or
- constitute an official MerlinAU release,

unless such a statement is factually correct or the distributor has
received authorization to make it.

## 5. Names of Authors and Maintainers

Pursuant to Section 7(d) of GPLv3, the names, usernames, or identities
of MerlinAU authors, contributors, or licensors may not be used for
publicity or promotional purposes in a manner that falsely implies
their sponsorship, endorsement, or approval of a modified or derivative
version.

This provision does not prohibit reasonable attribution or truthful
statements describing the origin or history of the software.

## 6. Trademark Rights Are Not Granted

Pursuant to Section 7(e) of GPLv3, no rights under trademark law are
granted by the GPLv3 license or by these Additional Terms for the use
of the following project marks:

- MerlinAU™
- MerlinAutoUpdate™
- the official MerlinAU logo or logos
- other distinctive MerlinAU project branding

Rights to copy, modify, and redistribute the underlying GPL-licensed
software are separate from rights that may exist in project names,
logos, and other trademarks.

Refer to `TRADEMARKS.md` for the MerlinAU trademark-use policy.

Nothing in this section is intended to prohibit uses of a mark that are
independently permitted by applicable trademark law, including
truthful use reasonably necessary to identify the origin of a
derivative work.

## 7. Official Project

For purposes of these Additional Terms, the official MerlinAU project
is the project maintained at:

https://github.com/ExtremeFiretop/MerlinAutoUpdate-Router

A fork, clone, mirror, modified distribution, or derivative work does
not become an official MerlinAU release merely because it originates
from the official repository.

Official status requires authorization from the person or persons
authorized to control the official MerlinAU project and its branding.

## 8. Relationship to GPLv3

These Additional Terms are intended to fall only within the categories
permitted by Section 7 of GPLv3.

They do not prohibit:

- creating a fork;
- privately modifying MerlinAU;
- publicly distributing a modified version;
- changing MerlinAU functionality;
- removing or replacing MerlinAU functionality; or
- creating an independently maintained derivative,

provided the applicable requirements of GPLv3 and valid Additional
Terms are followed.

If any provision of this document would constitute a "further
restriction" prohibited by GPLv3 rather than a valid Section 7
additional term, that provision is not intended to restrict rights
otherwise granted by GPLv3.

## 9. Applicable Version

These Additional Terms apply only to MerlinAU material released with a
notice stating that these Additional Terms apply.

Earlier copies of MerlinAU received without these Additional Terms
remain governed by the licensing terms applicable to those copies.

---

MerlinAU™ / MerlinAutoUpdate™

Official project:
https://github.com/ExtremeFiretop/MerlinAutoUpdate-Router
Loading