mirror of
https://github.com/jetkvm/kvm.git
synced 2026-05-21 05:20:35 +00:00
ci: redesign workflows into lint + build (#1330)
Replace 5 workflow files with 2 clean ones: - lint.yml: Go lint and UI lint as parallel jobs with consistent push + pull_request triggers (fixes fork PRs never getting UI lint) - build.yml: stripped to compile + test only, with pull_request trigger added (PRs now get build feedback before merge) Removed: - stale-issues.yml (permanent dry-run no-op) - smoketest.yml (frequently failing device tests) - dependabot.yml (automated dependency bumps) - golangci-lint.yml (folded into lint.yml) - ui-lint.yml (folded into lint.yml) Also fixed build.yml cache restore-keys to use a proper prefix fallback instead of duplicating the full key.
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: gomod
|
||||
directory: /
|
||||
schedule:
|
||||
interval: monthly
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: monthly
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: npm
|
||||
directory: /ui
|
||||
open-pull-requests-limit: 10
|
||||
schedule:
|
||||
interval: monthly
|
||||
+20
-46
@@ -1,71 +1,45 @@
|
||||
name: build image
|
||||
name: build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- main
|
||||
branches: [dev, main]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
name: Build
|
||||
if: github.event_name != 'pull_request_review' || github.event.review.state == 'approved'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Set up docker image context
|
||||
run: |
|
||||
./scripts/ci_helper.sh prepare
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build docker image
|
||||
uses: docker/build-push-action@v6
|
||||
- uses: actions/checkout@v5
|
||||
- name: Prepare Docker build context
|
||||
run: ./scripts/ci_helper.sh prepare
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
- uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ${{ env.DOCKER_BUILD_CONTEXT_DIR }}
|
||||
file: ${{ env.DOCKER_BUILD_CONTEXT_DIR }}/Dockerfile.build
|
||||
tags: ${{ env.DOCKER_BUILD_TAG }}
|
||||
push: false
|
||||
load: true
|
||||
- name: Set up Cmake cache
|
||||
uses: actions/cache@v5
|
||||
- uses: actions/cache@v5
|
||||
with:
|
||||
path: internal/native/cgo/build
|
||||
key: jetkvm-cgo-${{ hashFiles('internal/native/cgo/**/*.c', 'internal/native/cgo/**/*.h', 'internal/native/cgo/**/*.patch', 'internal/native/cgo/**/*.txt', 'internal/native/cgo/**/*.sh', '!internal/native/cgo/build/**') }}
|
||||
restore-keys: |
|
||||
jetkvm-cgo-${{ hashFiles('internal/native/cgo/**/*.c', 'internal/native/cgo/**/*.h', 'internal/native/cgo/**/*.patch', 'internal/native/cgo/**/*.txt', 'internal/native/cgo/**/*.sh', '!internal/native/cgo/build/**') }}
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
restore-keys: jetkvm-cgo-
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: "npm"
|
||||
cache: npm
|
||||
cache-dependency-path: "**/package-lock.json"
|
||||
- name: Set up Golang
|
||||
uses: actions/setup-go@v6
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "^1.25.1"
|
||||
- name: Build frontend
|
||||
run: |
|
||||
make frontend
|
||||
- name: Build application inside Docker container
|
||||
run: |
|
||||
./scripts/ci_helper.sh make build_dev
|
||||
run: make frontend
|
||||
- name: Build application
|
||||
run: ./scripts/ci_helper.sh make build_dev
|
||||
- name: Run tests
|
||||
run: |
|
||||
go test ./... -json > testreport.json
|
||||
- name: Make test cases
|
||||
run: |
|
||||
./scripts/ci_helper.sh make build_dev_test
|
||||
- name: Golang Test Report
|
||||
uses: becheran/go-testreport@v0.3.2
|
||||
run: go test ./... -json > testreport.json
|
||||
- uses: becheran/go-testreport@v0.3.2
|
||||
with:
|
||||
input: "testreport.json"
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: jetkvm-app
|
||||
path: |
|
||||
bin/jetkvm_app
|
||||
device-tests.tar.gz
|
||||
input: testreport.json
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
name: golangci-lint
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "go.sum"
|
||||
- "go.mod"
|
||||
- "**.go"
|
||||
- ".github/workflows/golangci-lint.yml"
|
||||
- ".golangci.yml"
|
||||
pull_request:
|
||||
|
||||
permissions: # added using https://github.com/step-security/secure-repo
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
golangci:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
pull-requests: read # for golangci/golangci-lint-action to fetch pull requests
|
||||
name: lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "^1.25.1"
|
||||
- name: Create empty resource directory
|
||||
run: |
|
||||
mkdir -p static && touch static/.gitkeep
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v8
|
||||
with:
|
||||
args: --verbose
|
||||
version: v2.4
|
||||
@@ -0,0 +1,41 @@
|
||||
name: lint
|
||||
on:
|
||||
push:
|
||||
branches: [dev, main]
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
go:
|
||||
name: Go
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "^1.25.1"
|
||||
- run: mkdir -p static && touch static/.gitkeep
|
||||
- uses: golangci/golangci-lint-action@v8
|
||||
with:
|
||||
args: --verbose
|
||||
version: v2.4
|
||||
|
||||
ui:
|
||||
name: UI
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: npm
|
||||
cache-dependency-path: "**/package-lock.json"
|
||||
- run: npm ci
|
||||
working-directory: ui
|
||||
- run: npm run lint
|
||||
working-directory: ui
|
||||
@@ -1,174 +0,0 @@
|
||||
name: smoketest
|
||||
on:
|
||||
repository_dispatch:
|
||||
types: [smoketest]
|
||||
|
||||
jobs:
|
||||
ghbot_payload:
|
||||
name: Ghbot payload
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "GH_CHECK_RUN_ID=${{ github.event.client_payload.check_run_id }}"
|
||||
run: |
|
||||
echo "== START GHBOT_PAYLOAD =="
|
||||
cat <<'GHPAYLOAD_EOF' | base64
|
||||
${{ toJson(github.event.client_payload) }}
|
||||
GHPAYLOAD_EOF
|
||||
echo "== END GHBOT_PAYLOAD =="
|
||||
deploy_and_test:
|
||||
runs-on: buildjet-4vcpu-ubuntu-2204
|
||||
name: Smoke test
|
||||
concurrency:
|
||||
group: smoketest-jk
|
||||
steps:
|
||||
- name: Download artifact
|
||||
run: |
|
||||
wget -O /tmp/jk.zip "${{ github.event.client_payload.artifact_download_url }}"
|
||||
unzip /tmp/jk.zip
|
||||
- name: Configure WireGuard and check connectivity
|
||||
run: |
|
||||
WG_KEY_FILE=$(mktemp)
|
||||
echo -n "$CI_WG_PRIVATE" > $WG_KEY_FILE && \
|
||||
sudo apt-get update && sudo apt-get install -y wireguard-tools && \
|
||||
sudo ip link add dev wg-ci type wireguard && \
|
||||
sudo ip addr add $CI_WG_IPS dev wg-ci && \
|
||||
sudo wg set wg-ci listen-port 51820 \
|
||||
private-key $WG_KEY_FILE \
|
||||
peer $CI_WG_PUBLIC \
|
||||
allowed-ips $CI_WG_ALLOWED_IPS \
|
||||
endpoint $CI_WG_ENDPOINT \
|
||||
persistent-keepalive 15 && \
|
||||
sudo ip link set up dev wg-ci && \
|
||||
sudo ip r r $CI_HOST via $CI_WG_GATEWAY dev wg-ci
|
||||
ping -c1 $CI_HOST || (echo "Failed to ping $CI_HOST" && sudo wg show wg-ci && ip r && exit 1)
|
||||
env:
|
||||
CI_HOST: ${{ vars.JETKVM_CI_HOST }}
|
||||
CI_WG_IPS: ${{ vars.JETKVM_CI_WG_IPS }}
|
||||
CI_WG_GATEWAY: ${{ vars.JETKVM_CI_GATEWAY }}
|
||||
CI_WG_ALLOWED_IPS: ${{ vars.JETKVM_CI_WG_ALLOWED_IPS }}
|
||||
CI_WG_PUBLIC: ${{ secrets.JETKVM_CI_WG_PUBLIC }}
|
||||
CI_WG_PRIVATE: ${{ secrets.JETKVM_CI_WG_PRIVATE }}
|
||||
CI_WG_ENDPOINT: ${{ secrets.JETKVM_CI_WG_ENDPOINT }}
|
||||
- name: Configure SSH
|
||||
run: |
|
||||
# Write SSH private key to a file
|
||||
SSH_PRIVATE_KEY=$(mktemp)
|
||||
echo "$CI_SSH_PRIVATE" > $SSH_PRIVATE_KEY
|
||||
chmod 0600 $SSH_PRIVATE_KEY
|
||||
# Configure SSH
|
||||
mkdir -p ~/.ssh
|
||||
cat <<EOF >> ~/.ssh/config
|
||||
Host jkci
|
||||
HostName $CI_HOST
|
||||
User $CI_USER
|
||||
StrictHostKeyChecking no
|
||||
UserKnownHostsFile /dev/null
|
||||
IdentityFile $SSH_PRIVATE_KEY
|
||||
EOF
|
||||
env:
|
||||
CI_USER: ${{ vars.JETKVM_CI_USER }}
|
||||
CI_HOST: ${{ vars.JETKVM_CI_HOST }}
|
||||
CI_SSH_PRIVATE: ${{ secrets.JETKVM_CI_SSH_PRIVATE }}
|
||||
- name: Run tests
|
||||
run: |
|
||||
set -e
|
||||
echo "+ Copying device-tests.tar.gz to remote host"
|
||||
ssh jkci "cat > /tmp/device-tests.tar.gz" < device-tests.tar.gz
|
||||
echo "+ Running go tests"
|
||||
ssh jkci ash << 'EOF'
|
||||
set -e
|
||||
TMP_DIR=$(mktemp -d)
|
||||
cd ${TMP_DIR}
|
||||
tar zxf /tmp/device-tests.tar.gz
|
||||
./gotestsum --format=testdox \
|
||||
--jsonfile=/tmp/device-tests.json \
|
||||
--post-run-command 'sh -c "echo $TESTS_FAILED > /tmp/device-tests.failed"' \
|
||||
--raw-command -- ./run_all_tests -json
|
||||
|
||||
GOTESTSUM_EXIT_CODE=$?
|
||||
if [ $GOTESTSUM_EXIT_CODE -ne 0 ]; then
|
||||
echo "❌ Tests failed (exit code: $GOTESTSUM_EXIT_CODE)"
|
||||
rm -rf ${TMP_DIR} /tmp/device-tests.tar.gz
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TESTS_FAILED=$(cat /tmp/device-tests.failed)
|
||||
if [ "$TESTS_FAILED" -ne 0 ]; then
|
||||
echo "❌ Tests failed $TESTS_FAILED tests failed"
|
||||
rm -rf ${TMP_DIR} /tmp/device-tests.tar.gz
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Tests passed"
|
||||
rm -rf ${TMP_DIR} /tmp/device-tests.tar.gz
|
||||
EOF
|
||||
ssh jkci "cat /tmp/device-tests.json" > device-tests.json
|
||||
- name: Set up Golang
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.24.4"
|
||||
- name: Golang Test Report
|
||||
uses: becheran/go-testreport@v0.3.2
|
||||
with:
|
||||
input: "device-tests.json"
|
||||
- name: Deploy application
|
||||
run: |
|
||||
set -e
|
||||
# Copy the binary to the remote host
|
||||
echo "+ Copying the application to the remote host"
|
||||
cat bin/jetkvm_app | gzip | ssh jkci "cat > /userdata/jetkvm/jetkvm_app.update.gz"
|
||||
# Deploy and run the application on the remote host
|
||||
echo "+ Deploying the application on the remote host"
|
||||
ssh jkci ash <<EOF
|
||||
# Extract the binary
|
||||
gzip -d /userdata/jetkvm/jetkvm_app.update.gz
|
||||
# Flush filesystem buffers to ensure all data is written to disk
|
||||
sync
|
||||
# Clear the filesystem caches to force a read from disk
|
||||
echo 1 > /proc/sys/vm/drop_caches
|
||||
# Reboot the application
|
||||
reboot -d 5 -f &
|
||||
EOF
|
||||
sleep 10
|
||||
echo "Deployment complete, waiting for JetKVM to come back online "
|
||||
function check_online() {
|
||||
for i in {1..60}; do
|
||||
if ping -c1 -w1 -W1 -q $CI_HOST >/dev/null; then
|
||||
echo "JetKVM is back online"
|
||||
return 0
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo "JetKVM did not come back online within 60 seconds"
|
||||
return 1
|
||||
}
|
||||
check_online
|
||||
env:
|
||||
CI_HOST: ${{ vars.JETKVM_CI_HOST }}
|
||||
- name: Run smoke tests
|
||||
run: |
|
||||
echo "+ Checking the status of the device"
|
||||
curl -v http://$CI_HOST/device/status && echo
|
||||
echo "+ Waiting for 15 seconds to allow all services to start"
|
||||
sleep 15
|
||||
echo "+ Collecting logs"
|
||||
local_log_tar=$(mktemp)
|
||||
ssh jkci ash > $local_log_tar <<'EOF'
|
||||
log_path=$(mktemp -d)
|
||||
dmesg > $log_path/dmesg.log
|
||||
cp /userdata/jetkvm/last.log $log_path/last.log
|
||||
tar -czf - -C $log_path .
|
||||
EOF
|
||||
tar -xf $local_log_tar
|
||||
cat dmesg.log last.log
|
||||
env:
|
||||
CI_HOST: ${{ vars.JETKVM_CI_HOST }}
|
||||
- name: Upload logs
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: device-logs
|
||||
path: |
|
||||
last.log
|
||||
dmesg.log
|
||||
device-tests.json
|
||||
@@ -1,100 +0,0 @@
|
||||
name: Close stale issues and PRs (dry-run)
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *' # Runs daily at 01:30 UTC
|
||||
workflow_dispatch: # Allow manual runs from the Actions tab
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v10
|
||||
with:
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# OVERVIEW — HOW THIS WORKS
|
||||
# 1) The job scans issues/PRs once per run.
|
||||
# 2) If an item has had no activity for `days-before-stale`, it’s labeled `Stale`
|
||||
# and receives the relevant “stale” comment.
|
||||
# 3) If there’s still no activity for `days-before-close` AFTER being marked
|
||||
# stale, the item is closed and receives a closing comment.
|
||||
# 4) Any new activity (comment, label change, commit, edit) clears `Stale`
|
||||
# and resets the timers if `remove-stale-when-updated` is true.
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
# ── TIMING / BEHAVIOR ────────────────────────────────────────────────
|
||||
# Number of idle days before applying the `Stale` label + stale comment.
|
||||
days-before-stale: 60
|
||||
|
||||
# Number of days AFTER staling with no activity before auto-closing.
|
||||
# (Measured from when `Stale` was added.) Set to -1 to never auto-close.
|
||||
days-before-close: 14
|
||||
|
||||
# If someone comments/updates, automatically remove `Stale` and reset timers.
|
||||
remove-stale-when-updated: true
|
||||
|
||||
# Don’t nag draft PRs; they are explicitly a work-in-progress stage.
|
||||
exempt-draft-pr: true
|
||||
|
||||
# Fetch ordering when scanning items. `updated` helps focus on the most recently touched.
|
||||
sort-by: updated
|
||||
|
||||
# ── MESSAGES (markdown) ──────────────────────────────────────────────
|
||||
stale-issue-message: |
|
||||
**This issue has been inactive for 60 days and is now marked as stale.**
|
||||
|
||||
To keep the tracker focused, older inactive issues are flagged.
|
||||
|
||||
If this still applies:
|
||||
- Add a comment with **reproduction steps**, **environment details**, and **JetKVM version**.
|
||||
- Verify whether it still occurs with the current build: see [OTA / Updates](https://jetkvm.com/docs/advanced-usage/ota-updates).
|
||||
- Any new comment or update will remove the *Stale* label automatically.
|
||||
|
||||
Issues not updated within 14 days after being marked stale may be closed.
|
||||
|
||||
stale-pr-message: |
|
||||
**This pull request has been inactive for 60 days and is now marked as stale.**
|
||||
|
||||
To continue:
|
||||
- Push a commit or add a comment about next steps — this removes the *Stale* label automatically.
|
||||
- Ensure the changes work with the current build: see [OTA / Updates](https://jetkvm.com/docs/advanced-usage/ota-updates).
|
||||
- If this is blocked or awaiting review, mention that for visibility.
|
||||
|
||||
PRs not updated within 14 days after being marked stale may be closed.
|
||||
|
||||
close-issue-message: |
|
||||
**Closing this issue due to extended inactivity.**
|
||||
|
||||
It has been 14 days since it was marked as stale without further updates.
|
||||
|
||||
If the problem persists:
|
||||
- Reopen this issue, or open a new one with **reproduction steps**, **logs**, **environment**, and **JetKVM version**.
|
||||
- Confirm behavior with the current build: [OTA / Updates](https://jetkvm.com/docs/advanced-usage/ota-updates).
|
||||
|
||||
close-pr-message: |
|
||||
**Closing this pull request due to extended inactivity.**
|
||||
|
||||
It has been 14 days since it was marked as stale with no updates or commits.
|
||||
|
||||
If the changes are still relevant:
|
||||
- Reopen this PR or submit a refreshed PR rebased on the latest code.
|
||||
- Confirm that it builds and works with the current build: [OTA / Updates](https://jetkvm.com/docs/advanced-usage/ota-updates).
|
||||
|
||||
# ── SAFETY / ROLLOUT ────────────────────────────────────────────────
|
||||
# DRY-RUN: log what would happen, but do NOT write labels/comments/close.
|
||||
debug-only: true
|
||||
|
||||
# Print a summary of how many items were staled/closed (or would be, in dry-run).
|
||||
enable-statistics: true
|
||||
|
||||
# Limit GitHub API operations per run (gentle start for large repos).
|
||||
# Increase later (e.g., 200–1000) once you’re confident with behavior.
|
||||
operations-per-run: 50
|
||||
|
||||
# ── LABELS ───────────────────────────────────────────────────────────
|
||||
# Names of the labels applied when staling items. Defaults shown for clarity.
|
||||
stale-issue-label: 'Stale'
|
||||
stale-pr-label: 'Stale'
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
name: ui-lint
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "ui/**"
|
||||
- "package.json"
|
||||
- "package-lock.json"
|
||||
- ".github/workflows/ui-lint.yml"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
ui-lint:
|
||||
name: UI Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: "22"
|
||||
cache: "npm"
|
||||
cache-dependency-path: "**/package-lock.json"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd ui
|
||||
npm ci
|
||||
- name: Lint UI
|
||||
run: |
|
||||
cd ui
|
||||
npm run lint
|
||||
Reference in New Issue
Block a user