From bfd488502601010a742aea55fceaa75a3dd3f52b Mon Sep 17 00:00:00 2001 From: Charlie Kolb Date: Wed, 14 Oct 2026 09:53:55 +0000 Subject: [PATCH] ci: Automate get-n8n fallback version updates (#40973) --- .github/WORKFLOWS.md | 1 + .../util-update-get-n8n-versions.yml | 118 ++++++++++++++++++ docker/get-n8n.sh | 4 +- 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/util-update-get-n8n-versions.yml diff --git a/.github/WORKFLOWS.md b/.github/WORKFLOWS.md index 309e8569768..a6edf1bdc90 100644 --- a/.github/WORKFLOWS.md +++ b/.github/WORKFLOWS.md @@ -600,6 +600,7 @@ Push to master | Daily 08:00 | `build-v3-nightly.yml` | Nightly v3 Docker images | | Monday 00:00 | `util-update-node-popularity.yml` | Node usage stats | | Monday 02:00 | `test-e2e-coverage-weekly.yml` | Weekly E2E coverage | +| Wednesday 04:00 | `util-update-get-n8n-versions.yml` | get-n8n stable versions | | Saturday 22:00 | `test-evals-ai.yml` | AI workflow evals | | 1st of month 04:00 | `util-refresh-cubic-schema.yml` | Refresh vendored cubic schema | diff --git a/.github/workflows/util-update-get-n8n-versions.yml b/.github/workflows/util-update-get-n8n-versions.yml new file mode 100644 index 00000000000..21b403ac47c --- /dev/null +++ b/.github/workflows/util-update-get-n8n-versions.yml @@ -0,0 +1,118 @@ +name: 'Util: Update get-n8n Versions' + +on: + schedule: + # Run every Wednesday at 04:00 UTC. + - cron: '0 4 * * 3' + workflow_dispatch: + +permissions: {} + +concurrency: + group: update-get-n8n-versions + cancel-in-progress: false + +jobs: + update-versions: + name: Update get-n8n versions + if: >- + github.ref_name == github.event.repository.default_branch && + (github.event_name == 'workflow_dispatch' || + (github.event_name == 'schedule' && github.repository == 'n8n-io/n8n')) + runs-on: ubuntu-latest + timeout-minutes: 25 + permissions: + contents: read + steps: + - name: Generate GitHub App Token + id: generate-token + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + with: + app-id: ${{ secrets.N8N_ASSISTANT_APP_ID }} + private-key: ${{ secrets.N8N_ASSISTANT_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write + + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Resolve stable versions + id: versions + env: + GH_TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + n8n_version="$(gh api repos/n8n-io/n8n/releases/latest --jq '.tag_name | sub("^n8n@"; "")')" + + registry_token="$(curl -fsSL --retry 3 'https://ghcr.io/token?scope=repository:n8n-io/n8n-sandbox-service-api:pull' | jq -er '.token')" + stable_digest="$(docker buildx imagetools inspect \ + 'ghcr.io/n8n-io/n8n-sandbox-service-api:stable' \ + --format '{{json .Manifest}}' | jq -er '.digest')" + sandbox_version='' + while IFS= read -r version; do + version_digest="$(docker buildx imagetools inspect \ + "ghcr.io/n8n-io/n8n-sandbox-service-api:${version}" \ + --format '{{json .Manifest}}' | jq -er '.digest')" + if [ "$version_digest" = "$stable_digest" ]; then + sandbox_version="$version" + break + fi + done < <(curl -fsSL --retry 3 \ + -H "Authorization: Bearer $registry_token" \ + 'https://ghcr.io/v2/n8n-io/n8n-sandbox-service-api/tags/list?n=1000' | + jq -r '.tags[]' | + grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | + sort -Vr) + + printf '%s\n' "$n8n_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' + printf '%s\n' "$sandbox_version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$' + + for image in api runner-dind sandbox; do + docker manifest inspect "ghcr.io/n8n-io/n8n-sandbox-service-${image}:${sandbox_version}" >/dev/null + done + + sed -i "s/^FALLBACK_N8N_VERSION=.*/FALLBACK_N8N_VERSION=\"${n8n_version}\"/" docker/get-n8n.sh + sed -i "s/^SANDBOX_VERSION=.*/SANDBOX_VERSION=\"${sandbox_version}\"/" docker/get-n8n.sh + + echo "n8n_version=$n8n_version" >> "$GITHUB_OUTPUT" + echo "sandbox_version=$sandbox_version" >> "$GITHUB_OUTPUT" + + - name: Check for changes + id: changes + run: | + if git diff --quiet -- docker/get-n8n.sh; then + echo 'has-changes=false' >> "$GITHUB_OUTPUT" + else + echo 'has-changes=true' >> "$GITHUB_OUTPUT" + fi + + - name: Test installer upgrade + if: steps.changes.outputs.has-changes == 'true' + run: | + shellcheck docker/get-n8n.sh docker/test-get-n8n.sh + dash -n docker/get-n8n.sh + dash -n docker/test-get-n8n.sh + sh docker/test-get-n8n.sh --e2e + + - name: Create pull request + if: steps.changes.outputs.has-changes == 'true' + uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 + with: + token: ${{ steps.generate-token.outputs.token }} + add-paths: docker/get-n8n.sh + commit-message: 'chore: Update get-n8n fallback versions' + labels: 'automation:scheduled-update' + title: 'chore: Update get-n8n fallback versions' + body: | + This automated PR updates the get-n8n fallback release to ${{ steps.versions.outputs.n8n_version }}. + It also updates the sandbox service release to ${{ steps.versions.outputs.sandbox_version }}. + + The workflow verified that all sandbox images use the same release. It also upgraded a legacy installation to these versions and checked the running stack. + + _Generated by the weekly get-n8n version update workflow._ + branch: update-get-n8n-versions + base: master + delete-branch: true + author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> + committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> diff --git a/docker/get-n8n.sh b/docker/get-n8n.sh index dc886061bfb..9e115f15721 100755 --- a/docker/get-n8n.sh +++ b/docker/get-n8n.sh @@ -15,11 +15,11 @@ set -eu SCRIPT_VERSION="1.4.0" # The version to install is derived from the latest stable GitHub release in # resolve_n8n_version(); this fallback only applies when that lookup fails. -FALLBACK_N8N_VERSION="2.32.0" +FALLBACK_N8N_VERSION="2.43.4" # Sandbox service release (API, runner and sandbox images ship together). # Pinned here, not resolved at run time: the stack definition must match it. # --upgrade moves existing installs to this pin. -SANDBOX_VERSION="1.3.4" +SANDBOX_VERSION="1.8.1" N8N_DIR="${N8N_DIR:-./n8n}" N8N_PORT=5678 SOURCE_URL="https://github.com/n8n-io/n8n/blob/master/docker/get-n8n.sh"