summaryrefslogtreecommitdiff
path: root/src/scripts/build-action.sh
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripts/build-action.sh')
-rw-r--r--src/scripts/build-action.sh135
1 files changed, 135 insertions, 0 deletions
diff --git a/src/scripts/build-action.sh b/src/scripts/build-action.sh
new file mode 100644
index 0000000..9c1d502
--- /dev/null
+++ b/src/scripts/build-action.sh
@@ -0,0 +1,135 @@
+#!/usr/bin/env bash
+# kenku --- crawl and reproduce github actions
+# Copyright © 2026 bdunahu <bdunahu@operationnull.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+function get_output_file {
+ local output_file action_file
+ action_file="action.yml"
+ [ ! -f "$action_file" ] && action_file="action.yaml"
+ output_file=$(grep -E '^\s*main:\s*' "${TO_ACT}${action_file}" | awk '{print $2}')
+ output_file=${output_file//\"/}
+ echo ${output_file//\'/}
+}
+
+function script_exists {
+ npm run | grep -q "^ $1"
+}
+
+ALL="$1"
+SHA="$2"
+DIR="$3"
+BUILD_FAILURE_DIR="$4"
+MISSING_ARTIFACT_DIR="$5"
+MAYBE_REPRODUCIBLE_DIR="$6"
+REPRODUCIBLE_DIR="$7"
+
+REPO_PRINTABLE="${ALL//\//_}_$SHA"
+# holds temporary print strings
+
+REPO=$(echo "$ALL" | awk -F'/' '{print $(1)}')
+TO_ACT=$(echo "$ALL" | awk -F'/' '{print $(2)}')
+REPO="$REPO/$TO_ACT"
+TO_ACT=$(echo "$ALL" | cut -d'/' -f3-)
+[[ -n "$TO_ACT" ]] && TO_ACT="$TO_ACT/"
+
+BUILD_DIR=$(mktemp -d)
+cd "$BUILD_DIR"
+
+echo "Cloning $REPO..."
+git clone "https://github.com/$REPO.git" repo > /dev/null 2>&1
+cd repo
+echo "Checking out $SHA"
+git checkout "$SHA" > /dev/null 2>&1
+
+# actions.yml refers to actions relatively, so if we parse
+# ../dist/foo/ as the action final build dir, we need to
+# refer to it relative to the curr dir of the script
+# this is one way
+DIST="$TO_ACT$(get_output_file)"
+# some actions just name an index.js in the root dir.
+# In cases they name a directory, we'll diff the full thing.
+[ "$(dirname "$DIST")" != "." ] && DIST="$(dirname "$DIST")"
+REFERENCE_DIST="$DIST.1"
+echo "Saving $DIST to $REFERENCE_DIST"
+
+mv "$DIST" "$REFERENCE_DIST"
+
+cd "$DIR"
+echo "Installing packages..."
+
+INSTALL=$(npm ci 2>&1)
+
+echo "Attempting to build..."
+
+TMP="owo what's the build command"
+# surely ONE of these will work...
+if COMM="release"; script_exists "$COMM"; then
+ echo "Trying '$COMM'..."
+ TMP=$(npm run "$COMM" 2>&1)
+elif COMM="package"; script_exists "$COMM"; then
+ echo "Trying '$COMM'..."
+ TMP=$(npm run "$COMM" 2>&1)
+elif COMM="bundle"; script_exists "$COMM"; then
+ echo "Trying '$COMM'..."
+ TMP=$(npm run "$COMM" 2>&1)
+elif COMM="build"; script_exists "$COMM"; then
+ echo "Trying '$COMM'..."
+ TMP=$(npm run "$COMM" 2>&1)
+fi
+
+# if the build fails, the developers may have failed to setup
+# the environment properly, or it uses deprecated features.
+# It may be that there is no build command at all! This needs
+# manual review.
+if [[ $? -ne 0 ]]; then
+ echo "$ALL did not build."
+ echo "$INSTALL" > "$BUILD_FAILURE_DIR/${REPO_PRINTABLE}.log"
+ echo "$TMP" >> "$BUILD_FAILURE_DIR/${REPO_PRINTABLE}.log"
+ exit 0 #don't kill outer script
+fi
+
+# return back to where we were
+cd "$BUILD_DIR"
+cd repo
+
+if [[ ! -d "$DIST" ]]; then
+ # TODO: if the dist dir wasn't produced, then the commands
+ # used were likely wrong
+ echo "$ALL did not produce artifacts."
+ echo "$INSTALL" >> "$MISSING_ARTIFACT_DIR/${REPO_PRINTABLE}.log"
+ echo "$TMP" >> "$MISSING_ARTIFACT_DIR/${REPO_PRINTABLE}.log"
+ exit 0
+fi
+
+# diffoscope will output binary diffs if line endings are not
+# comparable. --force forces it to convert binary files too.
+find "$REFERENCE_DIST" -type f -exec dos2unix --force {} \;
+
+# TODO: solves path errors in containers when using global install
+mkdir -p "$HOME/.npm-global"
+npm config set prefix "$HOME/.npm-global"
+export PATH="$HOME/.npm-global/bin:$PATH"
+
+# diffoscope uses to compare pretty
+npm install -g js-beautify
+
+diffoscope "$DIST" "$REFERENCE_DIST" \
+ --exclude-directory-metadata=yes \
+ --html "$MAYBE_REPRODUCIBLE_DIR/${REPO_PRINTABLE}.html"
+if [[ ! -f "$MAYBE_REPRODUCIBLE_DIR/${REPO_PRINTABLE}.html" ]]; then
+ touch "$REPRODUCIBLE_DIR/${REPO_PRINTABLE}.flag"
+ exit 0
+fi