diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index cc36cf7f..00000000 --- a/.github/dependabot.yml +++ /dev/null @@ -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 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7b0b12b8..2987007b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 \ No newline at end of file + input: testreport.json diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml deleted file mode 100644 index 05360ab9..00000000 --- a/.github/workflows/golangci-lint.yml +++ /dev/null @@ -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 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..330b7b80 --- /dev/null +++ b/.github/workflows/lint.yml @@ -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 diff --git a/.github/workflows/smoketest.yml b/.github/workflows/smoketest.yml deleted file mode 100644 index e1cefde8..00000000 --- a/.github/workflows/smoketest.yml +++ /dev/null @@ -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 <> ~/.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 < /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 diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml deleted file mode 100644 index 7a76d580..00000000 --- a/.github/workflows/stale-issues.yml +++ /dev/null @@ -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' diff --git a/.github/workflows/ui-lint.yml b/.github/workflows/ui-lint.yml deleted file mode 100644 index dc0da33d..00000000 --- a/.github/workflows/ui-lint.yml +++ /dev/null @@ -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