updated github workflows

This commit is contained in:
AndReicscs
2026-06-22 14:17:39 +00:00
parent 352dcecff3
commit 946303ccd2
7 changed files with 383 additions and 310 deletions
-132
View File
@@ -1,132 +0,0 @@
name: Hub Release & Publish
env:
WORKING_DIR: ./Hub
on:
push:
branches: [ "main" ]
tags: [ "v*.*.*" ]
paths: [ 'Hub/**' ]
workflow_dispatch:
jobs:
code-security:
name: "🛡️ Security & SAST Scans"
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # REQUIRED FOR CODEQL TO UPLOAD ALERTS
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache-dependency-path: ${{ env.WORKING_DIR }}/go.sum
# --- NEW: Build Vue Frontend ---
# Go requires the ui/dist folder to exist for the go:embed directive to compile
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: ${{ env.WORKING_DIR }}/ui/package-lock.json
- name: Build Vue Frontend
working-directory: ${{ env.WORKING_DIR }}/ui
run: |
npm ci
npm run build
# -------------------------------
# TODO: Uncomment this when we write the Fuzz tests!
# - name: Run Go Tests
# working-directory: ${{ env.WORKING_DIR }}
# run: go test -v ./...
# ----------------------------------------------------
# CODEQL SAST SCAN
# ----------------------------------------------------
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: 'go'
- name: Build for CodeQL
working-directory: ${{ env.WORKING_DIR }}
run: go build -v ./...
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:go/hub"
# ----------------------------------------------------
# TRIVY FILESYSTEM SCA SCAN
# ----------------------------------------------------
- name: Run Trivy Vulnerability Scanner (FS)
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: ${{ env.WORKING_DIR }}
format: 'table'
exit-code: '1'
severity: 'CRITICAL,HIGH'
publish-hub:
name: "🚀 Build & Publish Latest"
needs: [code-security]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Enables Raspberry Pi Support
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Automatically just tags everything pushed to main as "latest"
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/honeywire-hub
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
- name: Build and Push via Buildx
uses: docker/build-push-action@v5
with:
context: ${{ env.WORKING_DIR }}
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: true
sbom: true
- name: Summary
run: |
echo "### ✅ Hub Published Successfully" >> $GITHUB_STEP_SUMMARY
echo "Platforms: \`linux/amd64\`, \`linux/arm64\`" >> $GITHUB_STEP_SUMMARY
+44
View File
@@ -0,0 +1,44 @@
name: Publish Hub
on:
push:
tags:
- 'hub/v*.*.*'
permissions:
contents: write
packages: write
jobs:
publish:
name: Build and Push Hub Image
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Extract Version
id: vars
run: |
TAG_REF="${GITHUB_REF#refs/tags/}"
VERSION=$(echo "$TAG_REF" | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+')
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Log in to GitHub Container Registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build and Push Hub Docker Image
run: |
VERSION="${{ steps.vars.outputs.VERSION }}"
IMAGE_TAG="ghcr.io/${{ github.repository_owner }}/honeywire-hub:v$VERSION"
LATEST_TAG="ghcr.io/${{ github.repository_owner }}/honeywire-hub:latest"
docker build -t "$IMAGE_TAG" -t "$LATEST_TAG" -f Hub/Dockerfile .
docker push "$IMAGE_TAG"
docker push "$LATEST_TAG"
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: "Hub v${{ steps.vars.outputs.VERSION }}"
generate_release_notes: true
@@ -0,0 +1,134 @@
name: Publish Sensor to Registry
on:
push:
tags:
- 'sensor/**/v*.*.*'
permissions:
contents: write
packages: write
jobs:
publish:
name: "📦 Publish Sensor Manifest"
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract sensor name and version from tag
id: vars
run: |
TAG_REF="${GITHUB_REF#refs/tags/}"
SENSOR_NAME=$(echo "$TAG_REF" | sed 's|^sensor/||' | sed 's|/v[0-9].*$||')
VERSION=$(echo "$TAG_REF" | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+')
if [ -z "$SENSOR_NAME" ] || [ -z "$VERSION" ]; then
exit 1
fi
echo "SENSOR_NAME=$SENSOR_NAME" >> $GITHUB_OUTPUT
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Validate source manifest
id: validate
run: |
EXPECTED_ID="hw-sensor-${{ steps.vars.outputs.SENSOR_NAME }}"
SOURCE=$(find Sensors/official -name "*.json" | while read file; do
ID=$(jq -r '.id // empty' "$file" 2>/dev/null || true)
if [ "$ID" = "$EXPECTED_ID" ]; then
echo "$file"
exit 0
fi
done)
if [ -z "$SOURCE" ]; then
exit 1
fi
echo "SOURCE=$SOURCE" >> $GITHUB_OUTPUT
- name: Build versioned manifest
id: build
run: |
SOURCE="${{ steps.validate.outputs.SOURCE }}"
SENSOR_NAME="${{ steps.vars.outputs.SENSOR_NAME }}"
VERSION="${{ steps.vars.outputs.VERSION }}"
OUTPUT_FILE="${SENSOR_NAME}-v${VERSION}.json"
jq --arg ver "$VERSION" --arg tag "v$VERSION" \
'.version = $ver |
.deployment.image_tag = $tag |
if .deployment.init_containers then
.deployment.init_containers = [
.deployment.init_containers[] | .image_tag = $tag
]
else . end' \
"$SOURCE" > "/tmp/$OUTPUT_FILE"
echo "OUTPUT_FILE=$OUTPUT_FILE" >> $GITHUB_OUTPUT
- name: Log in to GitHub Container Registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Build and Push Docker Image
run: |
SOURCE="${{ steps.validate.outputs.SOURCE }}"
SENSOR_DIR=$(dirname "$SOURCE")
VERSION="${{ steps.vars.outputs.VERSION }}"
IMAGE_REPO=$(jq -r '.deployment.image_repository // empty' "$SOURCE")
if [ -z "$IMAGE_REPO" ]; then
exit 0
fi
IMAGE_TAG="$IMAGE_REPO:v$VERSION"
docker build -t "$IMAGE_TAG" -f "$SENSOR_DIR/Dockerfile" .
docker push "$IMAGE_TAG" | tee push_out.log
DIGEST=$(grep -o 'sha256:[a-f0-9]\{64\}' push_out.log | tail -n 1)
if [ -n "$DIGEST" ]; then
OUTPUT_FILE="${{ steps.build.outputs.OUTPUT_FILE }}"
jq --arg digest "$DIGEST" '.deployment.image_digest = $digest | if .deployment.init_containers then .deployment.init_containers[].image_digest = $digest else . end' "/tmp/$OUTPUT_FILE" > "/tmp/$OUTPUT_FILE.tmp" && mv "/tmp/$OUTPUT_FILE.tmp" "/tmp/$OUTPUT_FILE"
else
exit 1
fi
- name: Checkout registry-pages branch
run: |
cp scripts/build-registry-index.sh /tmp/build-registry-index.sh
chmod +x /tmp/build-registry-index.sh
git config user.name "HoneyWire CI"
git config user.email "ci@honeywire.dev"
if git ls-remote --exit-code --heads origin registry-pages >/dev/null 2>&1; then
git fetch origin registry-pages
git checkout registry-pages
else
git checkout --orphan registry-pages
git rm -rf . 2>/dev/null || true
echo "# HoneyWire Sensor Registry" > README.md
git add README.md
git commit -m "Initialize registry-pages branch"
fi
- name: Write versioned manifest to registry
run: |
OUTPUT_FILE="${{ steps.build.outputs.OUTPUT_FILE }}"
cp "/tmp/$OUTPUT_FILE" "./$OUTPUT_FILE"
- name: Rebuild index.json
run: /tmp/build-registry-index.sh
- name: Commit and push to registry-pages
run: |
SENSOR_NAME="${{ steps.vars.outputs.SENSOR_NAME }}"
VERSION="${{ steps.vars.outputs.VERSION }}"
OUTPUT_FILE="${{ steps.build.outputs.OUTPUT_FILE }}"
git add "$OUTPUT_FILE" index.json
git commit -m "registry: publish ${SENSOR_NAME} v${VERSION}"
git push origin registry-pages
+51
View File
@@ -0,0 +1,51 @@
name: Publish Wizard
on:
push:
tags:
- 'wizard/v*.*.*'
permissions:
contents: write
packages: write
jobs:
publish:
name: Build and Publish Wizard Binaries
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
- name: Extract Version
id: vars
run: |
TAG_REF="${GITHUB_REF#refs/tags/}"
VERSION=$(echo "$TAG_REF" | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+')
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Build Binaries
run: |
mkdir -p build
GOOS=linux GOARCH=amd64 go build -o build/honeywire-linux-amd64 wizard/cmd/wizard/main.go
GOOS=linux GOARCH=arm64 go build -o build/honeywire-linux-arm64 wizard/cmd/wizard/main.go
- name: Generate Checksums
run: |
cd build
sha256sum honeywire-* > checksums.txt
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: "Wizard v${{ steps.vars.outputs.VERSION }}"
files: |
build/honeywire-linux-amd64
build/honeywire-linux-arm64
build/checksums.txt
generate_release_notes: true
@@ -0,0 +1,102 @@
name: Rollback Sensor Registry
on:
workflow_dispatch:
inputs:
sensor_name:
description: 'Sensor name to rollback (e.g. file-canary) or "all" to rollback all sensors'
required: true
default: 'all'
jobs:
rollback:
name: "🔄 Rollback Sensor Version"
runs-on: ubuntu-latest
steps:
- name: Checkout main branch
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Prepare build script
run: |
cp scripts/build-registry-index.sh /tmp/build-registry-index.sh
chmod +x /tmp/build-registry-index.sh
- name: Checkout registry-pages branch
run: |
git config user.name "HoneyWire CI"
git config user.email "ci@honeywire.dev"
git fetch origin registry-pages
git checkout registry-pages
- name: Perform Rollback
id: rollback
env:
SENSOR_NAME: ${{ inputs.sensor_name }}
run: |
SENSOR_TARGET="$SENSOR_NAME"
if [ ! -f index.json ]; then
echo "❌ index.json not found in registry-pages branch!"
exit 1
fi
SENSORS=()
if [ "$SENSOR_TARGET" = "all" ]; then
# Extract sensor names from index.json (stripping the "hw-sensor-" prefix)
mapfile -t SENSORS < <(jq -r '.sensors[] | .id | sub("^hw-sensor-"; "")' index.json)
else
SENSORS=("$SENSOR_TARGET")
fi
echo "Rolling back sensors: ${SENSORS[*]}"
ROLLBACK_COUNT=0
for SENSOR in "${SENSORS[@]}"; do
# Find the highest version currently in the index for this sensor
LATEST_VERSION=$(jq -r --arg id "hw-sensor-$SENSOR" '.sensors[] | select(.id == $id) | .versions | map(.v) | sort_by(split(".") | map(tonumber)) | last' index.json)
if [ -z "$LATEST_VERSION" ] || [ "$LATEST_VERSION" = "null" ]; then
echo "⚠️ No versions found for sensor $SENSOR, skipping."
continue
fi
FILE_TO_DELETE="${SENSOR}-v${LATEST_VERSION}.json"
if [ -f "$FILE_TO_DELETE" ]; then
# Mark as deprecated instead of deleting
jq '.deprecated = true' "$FILE_TO_DELETE" > "$FILE_TO_DELETE.tmp" && mv "$FILE_TO_DELETE.tmp" "$FILE_TO_DELETE"
echo "✅ Marked $FILE_TO_DELETE as deprecated"
ROLLBACK_COUNT=$((ROLLBACK_COUNT + 1))
else
echo "⚠️ File $FILE_TO_DELETE not found, treating as manual deletion."
ROLLBACK_COUNT=$((ROLLBACK_COUNT + 1))
fi
done
if [ "$ROLLBACK_COUNT" -eq 0 ]; then
echo "⚠️ No rollbacks performed."
fi
echo "count=$ROLLBACK_COUNT" >> $GITHUB_OUTPUT
- name: Rebuild index.json
if: steps.rollback.outputs.count > 0
run: |
/tmp/build-registry-index.sh
echo "✅ index.json regenerated"
- name: Commit and push changes
if: steps.rollback.outputs.count > 0
env:
SENSOR_NAME: ${{ inputs.sensor_name }}
run: |
git add *.json
git commit -m "registry: rollback $SENSOR_NAME
Automated rollback of the latest versions via deprecation."
git push origin registry-pages
echo "🎉 Rollback complete!"
+52
View File
@@ -0,0 +1,52 @@
name: Security Scans
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:
permissions:
security-events: write
actions: read
contents: read
jobs:
analyze:
name: CodeQL Analysis
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'go', 'javascript', 'python' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
trivy:
name: Trivy FS Scan
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
ignore-unfixed: true
format: 'table'
severity: 'CRITICAL,HIGH'
-178
View File
@@ -1,178 +0,0 @@
name: Official Sensor Build & Publish
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
on:
push:
branches: [ "main" ]
tags: [ "v*.*.*" ]
paths: [ 'Sensors/official/**' ]
pull_request:
paths: [ 'Sensors/official/**' ]
workflow_dispatch:
jobs:
# ==========================================
# STAGE 1: DYNAMIC MATRIX GENERATOR
# ==========================================
detect-sensors:
name: "🔍 Detect Changed Official Sensors"
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.generate-matrix.outputs.matrix }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed directories
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: Sensors/official/**
dir_names: true
dir_names_max_depth: 3
json: true
escape_json: false
- name: Generate Independent Matrix
id: generate-matrix
env:
ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
# NEW: If it's a manual trigger OR a new Tag Release, build ALL sensors
if [ "${{ github.event_name }}" == "workflow_dispatch" ] || [ "${{ github.ref_type }}" == "tag" ]; then
MATRIX_JSON=$(find Sensors/official -mindepth 1 -maxdepth 1 -type d -exec test -f '{}/Dockerfile' \; -print | awk -F/ '{print $3}' | jq -R -s -c 'split("\n")[:-1]')
else
# On Push/PR: Parse the changed files JSON from the safe environment variable
if [ "$ALL_CHANGED_FILES" == "[]" ] || [ -z "$ALL_CHANGED_FILES" ]; then
MATRIX_JSON="[]"
else
MATRIX_JSON=$(echo "$ALL_CHANGED_FILES" | jq -c '[.[] | sub("Sensors/official/"; "")]')
fi
fi
echo "Generated Matrix: $MATRIX_JSON"
echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
# ==========================================
# STAGE 2: PARALLEL TEST, SCAN, & PUBLISH
# ==========================================
process-sensors:
name: "🚀 Process: ${{ matrix.sensor }}"
needs: detect-sensors
if: ${{ needs.detect-sensors.outputs.matrix != '[]' && needs.detect-sensors.outputs.matrix != '' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
sensor: ${{ fromJson(needs.detect-sensors.outputs.matrix) }}
permissions:
contents: read
packages: write
id-token: write
security-events: write # REQUIRED FOR CODEQL TO UPLOAD ALERTS
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25'
cache-dependency-path: Sensors/official/${{ matrix.sensor }}/go.sum
- name: Run Go Tests
working-directory: Sensors/official/${{ matrix.sensor }}
run: |
if [ -f "go.mod" ]; then
go test -v ./...
else
echo "No go.mod found, skipping native Go tests."
fi
# ----------------------------------------------------
# CODEQL SAST SCAN
# ----------------------------------------------------
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: 'go'
- name: Build for CodeQL
working-directory: Sensors/official/${{ matrix.sensor }}
run: |
if [ -f "go.mod" ]; then
go build -v ./...
fi
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
# Crucial for monorepos: prevents matrix jobs from overwriting each other's alerts
category: "/language:go/sensor:${{ matrix.sensor }}"
# ----------------------------------------------------
# TRIVY FILESYSTEM SCA SCAN
# ----------------------------------------------------
- name: Run Trivy FS Scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: Sensors/official/${{ matrix.sensor }}
format: 'table'
exit-code: '1'
severity: 'CRITICAL,HIGH'
# ----------------------------------------------------
# PUBLISHING STEPS (Only runs on Main Branch or Manual Trigger)
# ----------------------------------------------------
- name: Set up QEMU (ARM Support)
if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch'
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch'
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Docker metadata
if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' || github.ref_type == 'tag'
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository_owner }}/honeywire-${{ matrix.sensor }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
- name: Build and Push
if: github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch'
uses: docker/build-push-action@v5
with:
context: .
file: Sensors/official/${{ matrix.sensor }}/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.sensor }}
cache-to: type=gha,mode=max,scope=${{ matrix.sensor }}
provenance: true
sbom: true
- name: Summary
run: |
echo "### ✅ ${{ matrix.sensor }} Pipeline Complete" >> $GITHUB_STEP_SUMMARY