mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-21 20:20:03 +02:00
ci: preload Namespace tools and use native caches
This commit is contained in:
parent
1ad4e1500f
commit
313194ff50
2
.github/WORKFLOWS.md
vendored
2
.github/WORKFLOWS.md
vendored
|
|
@ -648,6 +648,8 @@ Composite actions in `.github/actions/`:
|
|||
|
||||
### setup-nodejs
|
||||
|
||||
For the opt-in Namespace Docker trial, see [Configure the Namespace Docker trial](namespace/README.md).
|
||||
|
||||
```yaml
|
||||
inputs:
|
||||
node-version: # default: '26.5.1'
|
||||
|
|
|
|||
2
.github/actionlint.yml
vendored
2
.github/actionlint.yml
vendored
|
|
@ -7,5 +7,5 @@ self-hosted-runner:
|
|||
- blacksmith-8vcpu-ubuntu-2204-arm
|
||||
- blacksmith-32vcpu-ubuntu-2204
|
||||
- blacksmith-32vcpu-ubuntu-2204-arm
|
||||
- nscloud-ubuntu-22.04-amd64-8x16
|
||||
- namespace-profile-n8n-docker-poc
|
||||
- ubuntu-slim
|
||||
|
|
|
|||
44
.github/actions/setup-nodejs/action.yml
vendored
44
.github/actions/setup-nodejs/action.yml
vendored
|
|
@ -1,11 +1,16 @@
|
|||
# This action works transparently on both Blacksmith and GitHub-hosted runners.
|
||||
# Blacksmith runners benefit from transparent caching and optional Docker layer caching.
|
||||
# GitHub-hosted runners use standard GitHub Actions caching.
|
||||
# The Namespace POC uses preloaded tools and native pnpm and Turbo caches.
|
||||
|
||||
name: 'Node.js Build Setup'
|
||||
description: 'Configures Node.js with pnpm, installs Aikido SafeChain for supply chain protection, installs dependencies, enables Turborepo caching, (optional) sets up Docker layer caching, and builds the project or an optional command.'
|
||||
|
||||
inputs:
|
||||
namespace-poc:
|
||||
description: 'Use the preloaded Namespace POC toolchain and native caches.'
|
||||
required: false
|
||||
default: 'false'
|
||||
node-version:
|
||||
description: 'Node.js version to use. Pinned to 26.5.1 by default for reproducible builds.'
|
||||
required: false
|
||||
|
|
@ -34,6 +39,14 @@ inputs:
|
|||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- name: Activate Namespace toolchain
|
||||
if: inputs.namespace-poc == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
echo /opt/n8n-ci/node/bin >> "$GITHUB_PATH"
|
||||
echo /opt/n8n-ci/pnpm >> "$GITHUB_PATH"
|
||||
echo "PNPM_HOME=$HOME/setup-pnpm" >> "$GITHUB_ENV"
|
||||
|
||||
# An empty key makes the builder use a local, uncached one. The job stays
|
||||
# green and loses the cache. Fail here instead.
|
||||
- name: Verify Docker cache key is set
|
||||
|
|
@ -51,7 +64,7 @@ runs:
|
|||
|
||||
# Windows cannot activate a POSIX home path from the restored cache.
|
||||
- name: Restore pnpm executable
|
||||
if: runner.os != 'Windows'
|
||||
if: runner.os != 'Windows' && inputs.namespace-poc != 'true'
|
||||
id: cache-pnpm-exe
|
||||
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
|
|
@ -60,7 +73,7 @@ runs:
|
|||
|
||||
- name: Setup pnpm
|
||||
id: setup-pnpm
|
||||
if: steps.cache-pnpm-exe.outputs.cache-hit != 'true'
|
||||
if: steps.cache-pnpm-exe.outputs.cache-hit != 'true' && inputs.namespace-poc != 'true'
|
||||
continue-on-error: true
|
||||
uses: pnpm/setup@703c52620218391530e48b9e8870d5c0082e1b9b # v2.1.0
|
||||
with:
|
||||
|
|
@ -98,7 +111,7 @@ runs:
|
|||
|
||||
# Save before later job failures can prevent cache creation.
|
||||
- name: Save pnpm executable
|
||||
if: runner.os != 'Windows' && steps.cache-pnpm-exe.outputs.cache-hit != 'true'
|
||||
if: runner.os != 'Windows' && steps.cache-pnpm-exe.outputs.cache-hit != 'true' && inputs.namespace-poc != 'true'
|
||||
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ~/setup-pnpm
|
||||
|
|
@ -117,13 +130,14 @@ runs:
|
|||
# quietly takes over. Caching the parent version dir captures the marker
|
||||
# alongside the toolchain. Key bumped to v2 to invalidate stale entries.
|
||||
- name: Restore Node.js Toolcache
|
||||
if: runner.os == 'Linux' && runner.arch == 'X64'
|
||||
if: runner.os == 'Linux' && runner.arch == 'X64' && inputs.namespace-poc != 'true'
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: /opt/hostedtoolcache/node/${{ inputs.node-version }}
|
||||
key: node-toolcache-v2-${{ runner.os }}-${{ runner.arch }}-${{ inputs.node-version }}
|
||||
|
||||
- name: Setup Node.js
|
||||
if: inputs.namespace-poc != 'true'
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
|
|
@ -169,8 +183,15 @@ runs:
|
|||
echo "path=$PNPM_CACHE_PATH" >> "$GITHUB_OUTPUT"
|
||||
echo "version=$(pnpm --version)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Mount Namespace pnpm cache
|
||||
if: inputs.namespace-poc == 'true' && inputs.install-command != ''
|
||||
uses: namespacelabs/nscloud-cache-action@1124a6f3ce44e5cf84cc22111530961f4d2a15f9 # v1
|
||||
with:
|
||||
cache: pnpm
|
||||
path: ${{ steps.pnpm-metadata-cache.outputs.path }}
|
||||
|
||||
- name: Restore pnpm metadata cache
|
||||
if: ${{ inputs.install-command != '' }}
|
||||
if: inputs.install-command != '' && inputs.namespace-poc != 'true'
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ${{ steps.pnpm-metadata-cache.outputs.path }}
|
||||
|
|
@ -190,6 +211,7 @@ runs:
|
|||
# radius across jobs, retry covers the first-job-per-key case where the
|
||||
# CDN must be hit. Keep the version in sync with the download step below.
|
||||
- name: Restore Aikido SafeChain Binary
|
||||
if: inputs.namespace-poc != 'true'
|
||||
id: cache-safe-chain
|
||||
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
|
|
@ -201,7 +223,7 @@ runs:
|
|||
# script also runs `setup-ci`, so on a cache miss this both downloads AND
|
||||
# activates; the Activate step below then re-runs `setup-ci` idempotently.
|
||||
- name: Download Aikido SafeChain
|
||||
if: steps.cache-safe-chain.outputs.cache-hit != 'true'
|
||||
if: steps.cache-safe-chain.outputs.cache-hit != 'true' && inputs.namespace-poc != 'true'
|
||||
run: |
|
||||
VERSION="1.5.20"
|
||||
EXPECTED_SHA256="0ad25efe15d1fa56105157a454d647223e78eb0c53d1f85e3d10afcd722e7bfd"
|
||||
|
|
@ -360,11 +382,17 @@ runs:
|
|||
# `fetch failed`, turning the whole job red. Skip it so the one Windows
|
||||
# build job stays green; Linux/Blacksmith jobs keep remote caching.
|
||||
- name: Configure Turborepo Cache
|
||||
if: steps.turbo-server.outputs.running != 'true' && runner.os != 'Windows'
|
||||
if: steps.turbo-server.outputs.running != 'true' && runner.os != 'Windows' && inputs.namespace-poc != 'true'
|
||||
uses: rharkor/caching-for-turbo@2238fae6eb9a9936f92356f54cb3660200d105e7 # v2.5.1
|
||||
with:
|
||||
server-port: 0
|
||||
|
||||
- name: Configure Namespace Turborepo cache
|
||||
if: inputs.namespace-poc == 'true'
|
||||
uses: namespace-actions/setup-turbocache@a94b84c111f2cc781a4a83c4d07a99f2c63e33d6 # v0
|
||||
with:
|
||||
team: n8n-docker-poc
|
||||
|
||||
- name: Setup Docker Builder for Docker Cache (Blacksmith)
|
||||
if: ${{ inputs.enable-docker-cache == 'true' && contains(runner.name, 'blacksmith') }}
|
||||
uses: useblacksmith/setup-docker-builder@a5256a73e30f09e37e3eceb8ca36043d17621d24 # v2.1.0
|
||||
|
|
@ -372,7 +400,7 @@ runs:
|
|||
cache-key: ${{ inputs.docker-cache-key }}
|
||||
|
||||
- name: Setup Docker Builder (GitHub fallback)
|
||||
if: ${{ inputs.enable-docker-cache == 'true' && !contains(runner.name, 'blacksmith') }}
|
||||
if: inputs.enable-docker-cache == 'true' && !contains(runner.name, 'blacksmith') && inputs.namespace-poc != 'true'
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
|
||||
- name: Build Project
|
||||
|
|
|
|||
29
.github/namespace/Dockerfile
vendored
Normal file
29
.github/namespace/Dockerfile
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# Keep these versions aligned with docker-build-push.yml, package.json, and setup-nodejs.
|
||||
ARG NAMESPACE_BASE_IMAGE_REF
|
||||
FROM ${NAMESPACE_BASE_IMAGE_REF}
|
||||
|
||||
USER root
|
||||
|
||||
RUN mkdir -p /opt/n8n-ci/node /opt/n8n-ci/pnpm /home/runner/.safe-chain/bin \
|
||||
&& curl --fail --silent --show-error --location --retry 3 \
|
||||
https://nodejs.org/dist/v26.10.0/node-v26.10.0-linux-x64.tar.xz -o /tmp/node.tar.xz \
|
||||
&& echo 'ca70e9e349de048b9522abb3adc05b3bd6f43c5ffd3ec57916c7da292f59f022 /tmp/node.tar.xz' | sha256sum -c - \
|
||||
&& tar -xJf /tmp/node.tar.xz -C /opt/n8n-ci/node --strip-components=1 \
|
||||
&& curl --fail --silent --show-error --location --retry 3 \
|
||||
https://github.com/pnpm/pnpm/releases/download/v12.4.2/pnpm-linux-x64.tar.gz -o /tmp/pnpm.tar.gz \
|
||||
&& echo 'ce1ed690fe9c2f091d7267e1afbe9380abb08bb577e95348fda194a41147d2ec /tmp/pnpm.tar.gz' | sha256sum -c - \
|
||||
&& tar -xzf /tmp/pnpm.tar.gz -C /opt/n8n-ci/pnpm \
|
||||
&& curl --fail --silent --show-error --location --retry 3 \
|
||||
https://github.com/AikidoSec/safe-chain/releases/download/1.5.20/safe-chain-linuxstatic-x64 \
|
||||
-o /home/runner/.safe-chain/bin/safe-chain \
|
||||
&& echo '13636819384f1e672c8c93c4ee6496113f9bde4b038ff9c59220fbb25f165199 /home/runner/.safe-chain/bin/safe-chain' | sha256sum -c - \
|
||||
&& chmod +x /home/runner/.safe-chain/bin/safe-chain \
|
||||
&& chown -R runner:runner /home/runner/.safe-chain \
|
||||
&& rm /tmp/node.tar.xz /tmp/pnpm.tar.gz
|
||||
|
||||
ENV PATH="/opt/n8n-ci/node/bin:/opt/n8n-ci/pnpm:${PATH}"
|
||||
|
||||
USER runner
|
||||
RUN test "$(node --version)" = 'v26.10.0' \
|
||||
&& test "$(pnpm --version)" = '12.4.2' \
|
||||
&& /home/runner/.safe-chain/bin/safe-chain -v
|
||||
35
.github/namespace/README.md
vendored
Normal file
35
.github/namespace/README.md
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# Configure the Namespace Docker trial
|
||||
|
||||
Use a Namespace workspace connected to this repository. Run these commands from the repository root.
|
||||
|
||||
1. Authenticate with `nsc login` or set `NSC_TOKEN_FILE` to your token file.
|
||||
2. Create the runner profile:
|
||||
|
||||
```bash
|
||||
PROFILE_ID=$(nsc github profile create --spec_file .github/namespace/profile.json -o json | jq -r .profile_id)
|
||||
```
|
||||
|
||||
For an existing profile, get its ID with `nsc github profile list -o json`.
|
||||
|
||||
3. Attach the custom image:
|
||||
|
||||
```bash
|
||||
nsc github profile update --profile_id "$PROFILE_ID" --dockerfile .github/namespace/Dockerfile -o json
|
||||
```
|
||||
|
||||
4. Wait for the image to become ready in the [Namespace profile dashboard](https://cloud.namespace.so/workspace/actions/profiles).
|
||||
5. Push your trial branch.
|
||||
6. Start an AMD64 build:
|
||||
|
||||
```bash
|
||||
gh workflow run docker-build-push.yml --ref "$(git branch --show-current)" \
|
||||
-f namespace_poc=true -f push_enabled=true -f include_arm64=false
|
||||
```
|
||||
|
||||
Verify that the job uses `namespace-profile-n8n-docker-poc` and passes the Node, pnpm, and SafeChain checks.
|
||||
Check that the pnpm cache mounts and Turbo uses the Namespace endpoint.
|
||||
Run the same commit again to measure warm caches.
|
||||
|
||||
When tool versions change, update the Dockerfile versions and checksums together.
|
||||
Match Node to `docker-build-push.yml`, pnpm to `package.json`, and SafeChain to `setup-nodejs/action.yml`.
|
||||
Repeat step 3 to rebuild the image.
|
||||
20
.github/namespace/profile.json
vendored
Normal file
20
.github/namespace/profile.json
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"tag": "n8n-docker-poc",
|
||||
"description": "n8n Docker trial with preloaded tools and Namespace caches",
|
||||
"os": "ubuntu-22.04",
|
||||
"instance_shape": {
|
||||
"virtual_cpu": 8,
|
||||
"memory_megabytes": 16384,
|
||||
"machine_arch": "amd64",
|
||||
"os": "linux"
|
||||
},
|
||||
"builder_mode": "USE_REMOTE_BUILDER",
|
||||
"cache_volume_settings": [
|
||||
{
|
||||
"volume_tag": "n8n-docker-poc",
|
||||
"volume_size_gb": 20,
|
||||
"bundled_git_mirror": true,
|
||||
"bundled_runner_actions_cache": true
|
||||
}
|
||||
]
|
||||
}
|
||||
23
.github/workflows/docker-build-push.yml
vendored
23
.github/workflows/docker-build-push.yml
vendored
|
|
@ -134,12 +134,21 @@ jobs:
|
|||
build-app:
|
||||
name: Build application for Docker images
|
||||
needs: determine-build-context
|
||||
runs-on: ${{ inputs.namespace_poc && 'nscloud-ubuntu-22.04-amd64-8x16' || 'blacksmith-8vcpu-ubuntu-2204' }}
|
||||
runs-on: ${{ inputs.namespace_poc && 'namespace-profile-n8n-docker-poc' || 'blacksmith-8vcpu-ubuntu-2204' }}
|
||||
timeout-minutes: 35
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code with Namespace
|
||||
if: inputs.namespace_poc
|
||||
uses: namespacelabs/nscloud-checkout-action@66f2dc6f6c42a8ac6c4e53473c4840006822831e # v9
|
||||
with:
|
||||
ref: ${{ inputs.ref }}
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
- name: Checkout code
|
||||
if: ${{ !inputs.namespace_poc }}
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ inputs.ref }}
|
||||
|
|
@ -149,6 +158,7 @@ jobs:
|
|||
- name: Setup and Build
|
||||
uses: ./.github/actions/setup-nodejs
|
||||
with:
|
||||
namespace-poc: ${{ inputs.namespace_poc && 'true' || 'false' }}
|
||||
# The image compiles native bindings against this Node version later.
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
build-command: pnpm build:n8n
|
||||
|
|
@ -168,7 +178,7 @@ jobs:
|
|||
build-and-push-docker:
|
||||
name: Build and Push Docker Image (${{ matrix.platform }})
|
||||
needs: [determine-build-context, build-app]
|
||||
runs-on: ${{ inputs.namespace_poc && 'nscloud-ubuntu-22.04-amd64-8x16' || matrix.runner }}
|
||||
runs-on: ${{ inputs.namespace_poc && 'namespace-profile-n8n-docker-poc' || matrix.runner }}
|
||||
timeout-minutes: 35
|
||||
permissions:
|
||||
actions: read
|
||||
|
|
@ -191,7 +201,16 @@ jobs:
|
|||
runners_date_manifest_tag: ${{ steps.determine-tags.outputs.runners_date_primary_tag }}
|
||||
runners_distroless_date_manifest_tag: ${{ steps.determine-tags.outputs.runners_distroless_date_primary_tag }}
|
||||
steps:
|
||||
- name: Checkout code with Namespace
|
||||
if: inputs.namespace_poc
|
||||
uses: namespacelabs/nscloud-checkout-action@66f2dc6f6c42a8ac6c4e53473c4840006822831e # v9
|
||||
with:
|
||||
ref: ${{ inputs.ref }}
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
- name: Checkout code
|
||||
if: ${{ !inputs.namespace_poc }}
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ inputs.ref }}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user