From 9711f54d3719f11c329469652c78f9f02b813a4b Mon Sep 17 00:00:00 2001
From: Ivan Spasov <78196474+Vankata453@users.noreply.github.com>
Date: Sun, 10 Jul 2022 17:16:56 +0300
Subject: [PATCH 1/2] Create an automatic workflow for updating add-ons
---
.github/workflows/main.yml | 48 ++++++++++++++++++
index-0_7.nfo | 49 +++++--------------
scripts/update_addon_index.sh | 91 +++++++++++++++++++++++++++++++++++
3 files changed, 152 insertions(+), 36 deletions(-)
create mode 100644 .github/workflows/main.yml
create mode 100644 scripts/update_addon_index.sh
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..ad1b777
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,48 @@
+name: Add-on auto-update
+
+on:
+ push:
+ branches: [ "master" ]
+ paths:
+ - repository/*.zip
+
+ workflow_dispatch:
+
+jobs:
+ update:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 2
+
+ - name: Get last commit
+ id: last-commit
+ run: |
+ echo "::set-output name=commit::$(git rev-parse HEAD)"
+
+ - name: Get modified add-ons
+ id: modified-addons
+ run: |
+ modified_addons=$(for path in `git diff --diff-filter=M --name-only HEAD~1..HEAD -- repository/` ; do basename $path ; done)
+ modified_addons="${modified_addons//'%'/'%25'}"
+ modified_addons="${modified_addons//$'\n'/'%0A'}"
+ modified_addons="${modified_addons//$'\r'/'%0D'}"
+ echo "::set-output name=list::$modified_addons"
+
+ - name: Run index file updater for each updated add-on
+ run: |
+ chmod +x scripts/update_addon_index.sh
+ while read file; do
+ echo "Executing script for modified add-on ${file}."
+ scripts/update_addon_index.sh -f $file -c ${{ steps.last-commit.outputs.commit }}
+ done <<< "${{ steps.modified-addons.outputs.list }}"
+
+ - name: Commit changes
+ run: |
+ git --version
+ git config --global user.email "supertux-addons"
+ git config --global user.name "SuperTux Add-ons"
+ git add \*.nfo
+ git commit -m "Update add-ons in latest index file"
+ git push
diff --git a/index-0_7.nfo b/index-0_7.nfo
index 82c9845..dceb81a 100644
--- a/index-0_7.nfo
+++ b/index-0_7.nfo
@@ -1,4 +1,3 @@
-;; automatically generated by build-addon-index.py
(supertux-addons
(supertux-addoninfo
(id "lolkat-levels")
@@ -10,7 +9,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/lolkat-levels.zip")
(md5 "6f623fa099262309387288b3efb13b4f")
)
-
(supertux-addoninfo
(id "octo-levels")
(version 2)
@@ -21,7 +19,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/octo-levels.zip")
(md5 "ff9e49ac0bfc50ffd6e75a3a549a90f3")
)
-
(supertux-addoninfo
(id "semajd-valley-of-chaos")
(version 2)
@@ -32,7 +29,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/semajd-valley-of-chaos.zip")
(md5 "29268305bf9f7e4110c3f74e3915ec4c")
)
-
(supertux-addoninfo
(id "rubberduck-levels")
(version 3)
@@ -43,7 +39,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/rubberduck-levels.zip")
(md5 "956cc3150d43427133eed6ce09cc0e12")
)
-
(supertux-addoninfo
(id "niso-yetis-revenge")
(version 3)
@@ -54,7 +49,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/niso-yetis-revenge.zip")
(md5 "2ba571148075d5b79c4c8b692e7fa1a7")
)
-
(supertux-addoninfo
(id "lmh-matties-world")
(version 4)
@@ -65,7 +59,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/lmh-matties-world.zip")
(md5 "7c50a91319df0901cd471664ca9095eb")
)
-
(supertux-addoninfo
(id "treskalle-island-of-moob")
(version 3)
@@ -76,7 +69,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/998ed9275a365933df84815600e952752d68a67b/repository/treskalle-island-of-moob.zip")
(md5 "187985f00be55b89e43e5de8f4970a4a")
)
-
(supertux-addoninfo
(id "hume-worldmaps")
(version 3)
@@ -87,7 +79,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/hume-worldmaps.zip")
(md5 "2947d3b806ba7908a8574e6d8bd617a2")
)
-
(supertux-addoninfo
(id "lmh-fionas-world")
(version 3)
@@ -98,7 +89,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/lmh-fionas-world.zip")
(md5 "d23d7322fd2a2cb8cbad8c83678aac49")
)
-
(supertux-addoninfo
(id "cschaefer-tux-strikes-back")
(version 3)
@@ -109,7 +99,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/cschaefer-tux-strikes-back.zip")
(md5 "54837d0386dbd4b38adb4905ce895653")
)
-
(supertux-addoninfo
(id "wolf-levels")
(version 2)
@@ -120,7 +109,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/wolf-levels.zip")
(md5 "3d383d4d8fab8da36ce5f52fc33b8328")
)
-
(supertux-addoninfo
(id "ctdabomb-worldmaps")
(version 2)
@@ -131,7 +119,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/ctdabomb-worldmaps.zip")
(md5 "5a17c1f6920ea337e27340657aedd8c7")
)
-
(supertux-addoninfo
(id "michel-the-frozen-mountains")
(version 3)
@@ -142,7 +129,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/michel-the-frozen-mountains.zip")
(md5 "e758815d8593d776313e7746dcd25255")
)
-
(supertux-addoninfo
(id "serano-islands")
(version 1)
@@ -153,7 +139,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/serano-islands_remastered.zip")
(md5 "18d58a1700590931ea7790402595e6d6")
)
-
(supertux-addoninfo
(id "language-pack")
(version 1)
@@ -164,7 +149,7 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/language-pack.zip")
(md5 "80de02550fe10fb9e8cd31828104398f")
)
- (supertux-addoninfo
+ (supertux-addoninfo
(id "ATTNW1")
(version 1)
(type "worldmap")
@@ -174,7 +159,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/ATTNW1.zip")
(md5 "2e86c1859517cafe4acdc56a9b71771d")
)
-
(supertux-addoninfo
(id "ATTNW2")
(version 1)
@@ -185,7 +169,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/ATTNW2.zip")
(md5 "8c00c9026ea6528c69049c03a630bee9")
)
-
(supertux-addoninfo
(id "grandmaster-journey")
(version 1)
@@ -196,7 +179,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/grandmaster-journey.zip")
(md5 "75e6cf0e4eea42bfae8eabaa79654b30")
)
-
(supertux-addoninfo
(id "manuel_desert_world")
(version 2)
@@ -207,7 +189,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/manuel-desert-world.zip")
(md5 "f2e087d5f69bf6f84d73976f2de39b0f")
)
-
(supertux-addoninfo
(id "toufik-levels")
(version 6)
@@ -218,7 +199,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/toufiks-levels.zip")
(md5 "dde248e28fa5a7ef0bc2358feb00a183")
)
-
(supertux-addoninfo
(id "Treasure_Mountain")
(version 1)
@@ -229,7 +209,6 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/treasure-mountain.zip")
(md5 "4fb77db8b0db267a6ddfd2e88901451e")
)
-
(supertux-addoninfo
(id "The_Big_Island")
(version 1)
@@ -240,8 +219,7 @@
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/the-big-island.zip")
(md5 "883d96c296377a0291ed62a05283a07d")
)
-
- (supertux-addoninfo
+ (supertux-addoninfo
(id "Arons_Levels")
(version 1)
(type "worldmap")
@@ -250,18 +228,17 @@
(license "CC-BY-SA 4.0 International")
(url "https://raw.githubusercontent.com/SuperTux/addons/4e4e23e01da309e10eacb32d7a24b19836807458/repository/arons-levels.zip")
(md5 "63418abb00bd866490caccdc35af4942")
- )
-
- (supertux-addoninfo
- (id "The_Crystal_Catacombs")
- (version 1)
- (type "worldmap")
- (title "The Crystal Catacombs")
- (author "Alasdair")
- (license "CC-BY-SA 4.0 International")
- (url "https://raw.githubusercontent.com/SuperTux/addons/92772fff2a7172afd70d0053f49be15225164cb5/repository/the-crystal-catacombs.zip")
- (md5 "45c183ed3aa552efac126a9053588611")
- )
+ )
+ (supertux-addoninfo
+ (id "The_Crystal_Catacombs")
+ (version 1)
+ (type "worldmap")
+ (title "The Crystal Catacombs")
+ (author "Alasdair")
+ (license "CC-BY-SA 4.0 International")
+ (url "https://raw.githubusercontent.com/SuperTux/addons/92772fff2a7172afd70d0053f49be15225164cb5/repository/the-crystal-catacombs.zip")
+ (md5 "45c183ed3aa552efac126a9053588611")
+ )
)
;; EOF ;;
diff --git a/scripts/update_addon_index.sh b/scripts/update_addon_index.sh
new file mode 100644
index 0000000..2a7a929
--- /dev/null
+++ b/scripts/update_addon_index.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+while getopts f:c: flag
+do
+ case "${flag}" in
+ f) file_name=${OPTARG};;
+ c) commit_hash=${OPTARG};;
+ *) echo "usage: $0 [-f] [-c]" >&2
+ exit 1 ;;
+ esac
+done
+
+#Detect if parameters are missing or empty.
+[[ -z "$file_name" ]] && { echo "No addon filename given." ; exit 1; }
+[[ ${file_name:(-4)} != ".zip" ]] && { echo "Given addon filename is invalid." ; exit 1; }
+[[ -z "$commit_hash" ]] && { echo "No commit hash given." ; exit 1; }
+
+echo "Filename: $file_name";
+echo "Commit hash: $commit_hash";
+
+FILE=index-0_7.nfo #The latest index file where changes should be written to. Change if needed!
+
+echo "" #Empty line
+echo "Fetching addon data:"
+
+addon_data=$(grep -A3 -B8 "$file_name\")" $FILE)
+addon_data_lines=$(grep -n -A3 -B8 "$file_name\")" $FILE | cut -f1 -d: | cut -f1 -d-)
+
+#Quit if no data is found for the addon.
+[[ -z "$addon_data" ]] && { echo "No data found for this addon." ; exit 1; }
+
+#Print initial addon data.
+echo "Addon data successfully found:"
+echo "$addon_data"
+echo "" #Empty line
+
+#Update version with +1.
+addon_version_line=$(echo "$addon_data" | grep -o "\(version [0-9]*\)")
+addon_version=$(echo "$addon_version_line" | sed -r 's/^.{8}//')
+addon_next_version=$((addon_version + 1))
+
+echo "Version: $addon_version"
+echo "Next Version: $addon_next_version"
+
+addon_data=$(echo "$addon_data" | sed -e "s/version [0-9]*/version ${addon_next_version}/g")
+
+echo "Version updated in addon data. Current status:"
+echo "$addon_data"
+echo "" #Empty line
+
+#Update commit hash in URL.
+addon_new_url="https://raw.githubusercontent.com/SuperTux/addons/${commit_hash}/repository"
+
+echo "New URL: $addon_new_url"
+
+addon_data=$(echo "$addon_data" | sed -e "s|\"https://raw.githubusercontent.com/SuperTux/addons/.*/repository|\"${addon_new_url}|g")
+
+echo "URL updated in addon data. Current status:"
+echo "$addon_data"
+echo "" #Empty line
+
+#Update MD5 checksum.
+addon_file=repository/$file_name
+addon_file_md5=($(md5sum "$addon_file"))
+
+[[ -z "$addon_file_md5" ]] && { echo "There was an error generating this addon's MD5." ; exit 1; }
+
+echo "Addon file: $addon_file"
+echo "Addon file MD5: $addon_file_md5"
+
+addon_data_before_md5=$addon_data
+addon_data=$(echo "$addon_data" | sed -e "s/md5 \".*\"/md5 \"${addon_file_md5}\"/g")
+
+#Exit if addon MD5 is equal to previous MD5.
+[[ "$addon_data" == "$addon_data_before_md5" ]] && { echo "Addon MD5 is the same as old MD5. Addon file has no changes. Exiting." ; exit 1; }
+
+echo "MD5 updated in addon data. Current status:"
+echo "$addon_data"
+echo "" #Empty line
+
+#Replace addon entry with updated one.
+IFS=$'\n'
+addon_data=($addon_data)
+addon_data_lines=($addon_data_lines)
+addon_data_first_line="${addon_data_lines[0]}"
+
+for line in "${addon_data_lines[@]}"
+do
+ data="${addon_data[$((line - addon_data_first_line))]}"
+ sed -i "${line}s@.*@${data}@g" $FILE
+ echo "Updated line ${line} in ${FILE}."
+done
From a571056a9f806ce1a13b3e271ed53f0ec4c45586 Mon Sep 17 00:00:00 2001
From: Vankata453 <78196474+Vankata453@users.noreply.github.com>
Date: Sat, 16 Jul 2022 18:36:45 +0300
Subject: [PATCH 2/2] Updates to README.md including workflow info
---
README.md | 62 ++++++++++++++-----------------------------------------
1 file changed, 16 insertions(+), 46 deletions(-)
diff --git a/README.md b/README.md
index d7f7436..d5fef0e 100644
--- a/README.md
+++ b/README.md
@@ -1,54 +1,21 @@
-SuperTux Addons
+SuperTux Add-ons
==============
-## Packaging your addon
+## Packaging your add-on
-To package your addon, you can use the "Package Add-on" option in the main level editor menu.
+To package your add-on, you can use the "Package Add-on" option in the main level editor menu.
-Additional information for addon .nfo files
-
-Addon .nfo files look like this:
+[Information about manual add-on packaging](https://github.com/SuperTux/supertux/wiki/Add-ons#manually-packaging-addons)
-```
-(supertux-addoninfo
- (id "octo-levels")
- (version 1)
- (type "worldmap")
- (title "Octo's Levels")
- (author "Octo")
- (license "GPL 2+ / CC-by-sa 3.0")
-)
-```
-
-The `id` is a identifier for this addon, it has to be unique across
-all addons, as it is used to compare the addons with new ones from
-other sources to find updates. It is recomment to use something like
-"{author}-{title}". The `id` must be all lowercase and only contain
-characters of the set "[a-z][0-9]-", underscore is not allowed as it
-is used for the version number.
-
-The `version` number is a simple integer, it should be increased each
-time the addon is changed.
+[Information about add-on .nfo files](https://github.com/SuperTux/supertux/wiki/Add-ons#nfo-files)
-The `type` gives an indication of what is contained within the addon,
-valid values are "worldmap", "world", "levelset". At the moment this
-is only a description for the user and doesn't have any impact on how
-the addon is handled.
+## Adding an add-on
+Adding an add-on involves authoring two commits. Here is what each one has to add/change:
-The .nfo file itself needs to be stored in the top-level directory of
-the addon and should be named by the unique id of the addon, i.e.
-`/octo-levels.nfo` in this example.
-
(supertux-addoninfo @@ -63,6 +30,9 @@ An addon data entry looks like this: )-* **addon-commit-hash** represents the full commit hash of your first commit, which adds/replaces your addon in the `repository/` directory. This is important to include, because it allows the current SuperTux release to always get its versions of all addons for backwards compatibility. -* **addon-md5-checksum** represents your new, modified addon archive's MD5 checksum hash. This needs to be updated every time the addon is updated, because the game will not be able to download your addon otherwise. The MD5 checksum is being used for checking the integrity of the addon. -* For the rest of the entries, the rules listed above for addon `.nfo` files also apply here. +* **addon-commit-hash** represents the full commit hash of your first commit, which adds your add-on in the `repository/` directory. This is important to include, because it allows the current SuperTux release to always get its versions of all add-ons for backwards compatibility. +* **addon-md5-checksum** represents your new add-on archive's MD5 checksum hash. The MD5 checksum is being used for checking the integrity of the add-on. +* For the rest of the entries, the rules listed for [add-on `.nfo` files](https://github.com/SuperTux/supertux/wiki/Add-ons#nfo-files) also apply here. + +## Updating an add-on +Add-ons are automatically updated in this repository. Updating the add-on archives in the `repository/` directory is all that has to be done by the user. The automatic workflow for updating add-ons in the latest index file will take care of the rest.