Skip to content

Nightly Build

Nightly Build #61

Workflow file for this run

name: Nightly Build
on:
schedule:
- cron: "0 6 * * *" # 06:00 UTC nightly
workflow_dispatch:
concurrency:
group: nightly
cancel-in-progress: true
jobs:
nightly-build:
runs-on: ubuntu-latest
outputs:
build_date: ${{ steps.capture.outputs.build_date }}
git_hash: ${{ steps.capture.outputs.git_hash }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Capture metadata
id: capture
run: |
echo "build_date=$(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> $GITHUB_OUTPUT
echo "git_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y pandoc rpm dpkg-dev
sudo apt-get install -y libarchive-zip-perl
- name: Install Python build dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install pyinstaller
- name: Install PythonTools
run: |
if [ ! -d PythonTools ]; then
git clone https://github.com/linktech-engineering-llc/PythonTools.git
fi
python3 -m pip install PythonTools/
- name: Make scripts executable
run: chmod +x packaging/*.sh
- name: Build all artifacts
run: ./packaging/build_all.sh
- name: Normalize RPM filename
run: |
OUT=packaging/output
RPM_SRC=$(find packaging/rpmbuild/RPMS/x86_64 -type f -name "*.rpm" | head -n 1)
if [[ -n "$RPM_SRC" ]]; then
ARCH=$(echo "$RPM_SRC" | sed -n 's/.*\.\(.*\)\.rpm/\1/p')
VERSION=$(basename "$RPM_SRC" | sed -n 's/RunUpdates-\(.*\)-.*\.rpm/\1/p')
mv "$RPM_SRC" "$OUT/RunUpdates_${VERSION}.${ARCH}.rpm"
fi
- name: Collect artifacts
run: |
mkdir -p artifacts
cp packaging/output/RunUpdates_* artifacts/
- name: Generate metadata.json
run: |
mkdir -p artifacts
# Detect toolchain versions
PYTHON_VERSION=$(python3 --version | awk '{print $2}')
PYINSTALLER_VERSION=$(pyinstaller --version 2>/dev/null || echo "unknown")
BUILDER_OS="ubuntu-latest"
# Start metadata.json
cat > artifacts/metadata.json <<EOF
{
"meta_version": 2,
"build": {
"date": "${{ steps.capture.outputs.build_date }}",
"commit": "${{ steps.capture.outputs.git_hash }}",
"branch": "nightly",
"workflow_run_id": $GITHUB_RUN_ID
},
"toolchain": {
"python": "$PYTHON_VERSION",
"pyinstaller": "$PYINSTALLER_VERSION",
"builder_os": "$BUILDER_OS"
},
"artifacts": [
EOF
FIRST=1
for f in artifacts/RunUpdates_*; do
NAME=$(basename "$f")
SIZE=$(stat -c%s "$f")
SHA=$(sha256sum "$f" | awk '{print $1}')
CRC=$(crc32 "$f")
# Detect type, OS, arch
case "$NAME" in
*.deb)
TYPE="deb"
OS="linux"
ARCH="amd64"
;;
*.rpm)
TYPE="rpm"
OS="linux"
ARCH="x86_64"
;;
*.zip)
TYPE="zip"
OS="windows"
ARCH="x86_64"
;;
*.tgz|*.tar.gz)
TYPE="tgz"
OS="linux"
ARCH="amd64"
;;
*)
TYPE="unknown"
OS="unknown"
ARCH="unknown"
;;
esac
if [ $FIRST -eq 0 ]; then
echo "," >> artifacts/metadata.json
fi
FIRST=0
cat >> artifacts/metadata.json <<EOF
{
"name": "$NAME",
"type": "$TYPE",
"os": "$OS",
"arch": "$ARCH",
"size": $SIZE,
"sha256": "$SHA",
"crc32": "$CRC"
}
EOF
done
# Close JSON
cat >> artifacts/metadata.json <<EOF
]
}
EOF
- name: Upload nightly artifacts
uses: actions/upload-artifact@v4
with:
name: nightly-runupdates
path: artifacts
- name: Validate metadata.json
run: |
pip install jsonschema
python3 packaging/metadata/validate.py artifacts/metadata.json
- name: Remove existing nightly assets
env:
GH_TOKEN: ${{ github.token }}
run: |
ASSETS=$(gh release view nightly --json assets --jq '.assets[].name')
for asset in $ASSETS; do
if [[ "$asset" == RunUpdates* ]]; then
echo "Deleting asset: $asset"
gh release delete-asset nightly "$asset" --yes
fi
done
- name: Upload artifacts to nightly release
uses: softprops/action-gh-release@v1
with:
tag_name: nightly
files: packaging/output/*
publish-dashboard:
runs-on: ubuntu-latest
needs: nightly-build
steps:
- name: Checkout gh-pages branch
uses: actions/checkout@v4
with:
ref: gh-pages
- name: Preserve existing dashboard files
run: |
mkdir -p dashboard
cp dashboard.js dashboard.js.bak 2>/dev/null || true
- name: Download nightly artifacts
uses: actions/download-artifact@v4
with:
name: nightly-runupdates
path: artifacts
- name: Copy metadata.json to dashboard root
run: |
cp artifacts/metadata.json .
- name: Generate dashboard HTML
run: |
META=artifacts/metadata.json
RELEASE_URL="https://github.com/Linktech-Engineering-LLC/RunUpdates/releases/download/nightly"
mkdir -p dashboard
rm -f dashboard/*
curl -s -o dashboard/qr.png \
"https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=https://linktech-engineering-llc.github.io/RunUpdates/"
cat > dashboard/index.html <<EOF
<html>
<head>
<title>RunUpdates Nightly Dashboard</title>
<style>
body { font-family: Arial; margin: 20px; }
table { border-collapse: collapse; margin-top: 10px; width: 100%; }
th, td { padding: 8px 12px; border: 1px solid #ccc; }
th { background: #f0f0f0; }
.badge-row img { margin-right: 8px; }
.download-btn {
background: #0078d4;
color: white;
padding: 6px 12px;
border-radius: 4px;
text-decoration: none;
}
.download-btn:hover {
background: #005a9e;
}
.qr { margin-top: 20px; }
</style>
</head>
<body>
<h1>RunUpdates Nightly Dashboard</h1>
<div class="badge-row">
<img src="https://img.shields.io/badge/version-loading-blue" id="version-badge">
<img src="https://img.shields.io/badge/date-loading-lightgrey" id="date-badge">
<img src="https://img.shields.io/badge/python-loading-yellow" id="python-badge">
<img src="https://img.shields.io/badge/pyinstaller-loading-orange" id="pyi-badge">
</div>
<h2>Build Metadata</h2>
<div id="build-info"></div>
<h2>Artifacts</h2>
<div id="artifact-table"></div>
<div class="qr">
<h2>QR Code</h2>
<img src="qr.png" alt="QR Code">
</div>
<script src="dashboard.js"></script>
</body>
</html>
- name: Restore dashboard.js
run: |
if [ -f dashboard.js.bak ]; then
mv dashboard.js.bak dashboard.js
fi
- name: Publish dashboard to gh-pages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
cp -r dashboard/* .
git add .
git commit -m "Update nightly dashboard" || echo "No changes"
git push origin gh-pages