Split CI/CD workflows for ENSNode and ENSDb Playground deployments#2338
Split CI/CD workflows for ENSNode and ENSDb Playground deployments#2338tk-o wants to merge 4 commits into
Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@greptile review |
📝 WalkthroughWalkthroughReplaces Railway-based deployment inspection with ENSNode ChangesVercel Promotion: Railway → ENSNode Environment
ENSNode + ENSDb Playground Workflow Updates
Sequence Diagram(s)sequenceDiagram
participant Workflow as deploy_switch_ensnode_environment
participant Action as promote_vercel_deployment
participant ENSNodeAPI as ENSNode /indexing-status
participant Skopeo as skopeo inspect
participant Vercel as Vercel API
Workflow->>Action: ensnode_environment=green|blue|yellow
Action->>ENSNodeAPI: GET /indexing-status
ENSNodeAPI-->>Action: ensIndexer version
Action->>Skopeo: inspect ENSINDEXER_IMAGE
Skopeo-->>Action: commit SHA
Action->>Vercel: find deployment by SHA
Vercel-->>Action: deployment matched
Action->>Vercel: promote to production
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
This PR splits the “switch production environment” workflow so ENSNode routing can be switched independently of ENSDb Playground routing, and expands ENSNode’s switcher to support a third (yellow) environment.
Changes:
- Add
yellowas a selectable target environment for ENSNode switching, and remove ENSDb Playground routing from the ENSNode switch workflow. - Introduce a new, dedicated workflow to switch ENSDb Playground routing between blue/green.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| .github/workflows/deploy_switch_ensnode_environment.yml | Adds yellow option + ENSNode-specific Slack titles; removes ENSDb Playground router switching from this workflow. |
| .github/workflows/deploy_switch_ensdb_playground_environment.yml | New workflow to switch only the ENSDb Playground Traefik router between blue and green. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Greptile SummaryThis PR splits the previously unified environment-switch workflow into two independent workflows — one for ENSNode and one for ENSDb Playground — and replaces the Railway GraphQL API version lookup with a direct call to the ENSNode
Confidence Score: 4/5Safe to merge with awareness that triggering a yellow switch will leave the Promote steps in a broken state until a guard is added. The two Promote steps in the ENSNode workflow run unconditionally for all three targets. When yellow is selected, the promote script calls
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[workflow_dispatch] --> B{target}
B -->|green / blue / yellow| C[Switch ENSNode Environment]
B -->|green / blue| D[Switch ENSDb Playground Environment]
C --> C1[Calculate env vars / SLACK_TITLE]
C1 --> C2[Switch Traefik Routing\nAlpha / Mainnet / Sepolia / ENSRainbow]
C2 --> C3[Promote ENSAdmin Vercel Deployment]
C3 --> C4[Promote Example App Vercel Deployment]
C4 --> C5[Send Slack Notification]
D --> D1[Calculate env vars / SLACK_TITLE]
D1 --> D2[Switch Traefik Routing\nensdb-playground-router]
D2 --> D3[Send Slack Notification]
C3 & C4 --> P[promote_vercel_deployment action]
P --> P1[curl ENSNode indexing-status endpoint\nhttps://api.alpha.ENV.ensnode.io/api/indexing-status]
P1 --> P2[Extract version → construct image tag]
P2 --> P3[skopeo inspect → get commit SHA]
P3 --> P4[Vercel API: find deployment by SHA]
P4 --> P5[Vercel API: promote to production]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[workflow_dispatch] --> B{target}
B -->|green / blue / yellow| C[Switch ENSNode Environment]
B -->|green / blue| D[Switch ENSDb Playground Environment]
C --> C1[Calculate env vars / SLACK_TITLE]
C1 --> C2[Switch Traefik Routing\nAlpha / Mainnet / Sepolia / ENSRainbow]
C2 --> C3[Promote ENSAdmin Vercel Deployment]
C3 --> C4[Promote Example App Vercel Deployment]
C4 --> C5[Send Slack Notification]
D --> D1[Calculate env vars / SLACK_TITLE]
D1 --> D2[Switch Traefik Routing\nensdb-playground-router]
D2 --> D3[Send Slack Notification]
C3 & C4 --> P[promote_vercel_deployment action]
P --> P1[curl ENSNode indexing-status endpoint\nhttps://api.alpha.ENV.ensnode.io/api/indexing-status]
P1 --> P2[Extract version → construct image tag]
P2 --> P3[skopeo inspect → get commit SHA]
P3 --> P4[Vercel API: find deployment by SHA]
P4 --> P5[Vercel API: promote to production]
Reviews (2): Last reviewed commit: "Apply AI PR feedback" | Re-trigger Greptile |
…-deployment-prod-switch
9aae3d0 to
3ca2bd4
Compare
| fi | ||
| --fail \ | ||
| --url "$INDEXING_STATUS_URL" | \ | ||
| jq -r '.stackInfo.ensIndexer.versionInfo.ensIndexer') |
There was a problem hiding this comment.
promote_vercel_deployment.sh reconstructs the ENSIndexer image tag from the reported semver version (ensindexer:<version>), which does not exist for release-candidate/preview deployments, so skopeo inspect fails — and because the promote steps run after the irreversible Traefik routing switch, the workflow aborts with production already moved to the new backend but the frontend left un-promoted.
|
@greptile review |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/deploy_switch_ensnode_environment.yml (1)
19-22: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winSerialize production environment switches.
This job mutates shared production routing and promotes Vercel deployments; concurrent manual runs can interleave those operations and leave routing/promotions split across targets. Add job-level concurrency with queuing, not cancellation.
Proposed fix
switch-environment: # NOTE: this needs to run on GH runner because of some obscure skopeo permissions thing runs-on: ubuntu-latest name: Switch Environment to ${{ inputs.target }} + concurrency: + group: deploy-switch-ensnode-environment + cancel-in-progress: false env:🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/deploy_switch_ensnode_environment.yml around lines 19 - 22, Add job-level concurrency to the switch-environment job so only one production environment switch runs at a time, and configure it to queue rather than cancel in-progress or pending runs. Update the switch-environment job in the workflow that uses the ubuntu-latest runner and the “Switch Environment to ${{ inputs.target }}” name, using a stable concurrency group for this workflow/job so concurrent manual triggers serialize cleanly.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/actions/promote_vercel_deployment/promote_vercel_deployment.sh:
- Around line 41-48: The ENSNode indexing-status fetch in
promote_vercel_deployment.sh is unbounded and can hang the promotion job if the
endpoint stalls. Update the curl call used to populate ENSNODE_VERSION with
explicit connection and total timeouts, plus a small retry budget, while keeping
the existing INDEXING_STATUS_URL and jq parsing flow intact. Use the existing
promote_vercel_deployment.sh request block as the place to apply the
timeout/retry settings so the workflow fails fast instead of waiting for the
full job timeout.
In @.github/workflows/deploy_switch_ensdb_playground_environment.yml:
- Around line 6-20: The manual environment switch workflow can race because
multiple dispatches of switch-environment mutate the same Traefik routing key at
once. Add a workflow-level deployment lock using the workflow’s concurrency
controls so only one run can execute or queue at a time, and apply it to the
deploy_switch_ensdb_playground_environment workflow around the existing
workflow_dispatch/job setup.
- Around line 27-30: The Checkout repository step in the deploy workflow needs
hardening: `actions/checkout` is currently tag-pinned and leaves credentials in
git config by default. Update the `Checkout repository` step to use a full
commit SHA for `actions/checkout` and set `persist-credentials` to false unless
later steps in the workflow require authenticated git access.
- Around line 55-56: The local action referenced by Send Slack Notification is
missing required metadata, causing actionlint to reject the workflow. Update
.github/actions/send_slack_notification/action.yml to add a top-level
description field alongside the existing action metadata so the uses step for
send_slack_notification is lint-valid.
---
Outside diff comments:
In @.github/workflows/deploy_switch_ensnode_environment.yml:
- Around line 19-22: Add job-level concurrency to the switch-environment job so
only one production environment switch runs at a time, and configure it to queue
rather than cancel in-progress or pending runs. Update the switch-environment
job in the workflow that uses the ubuntu-latest runner and the “Switch
Environment to ${{ inputs.target }}” name, using a stable concurrency group for
this workflow/job so concurrent manual triggers serialize cleanly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 03851eab-5def-4e1c-88eb-8fc82bbe4b61
📒 Files selected for processing (4)
.github/actions/promote_vercel_deployment/action.yml.github/actions/promote_vercel_deployment/promote_vercel_deployment.sh.github/workflows/deploy_switch_ensdb_playground_environment.yml.github/workflows/deploy_switch_ensnode_environment.yml
| # first, get the deployed ENSNode version from the ENSApi indexing-status endpoint | ||
| INDEXING_STATUS_URL="https://api.alpha.${ENSNODE_ENVIRONMENT}.ensnode.io/api/indexing-status" | ||
| ENSNODE_VERSION=$(curl \ | ||
| --silent \ | ||
| --show-error \ | ||
| --url https://backboard.railway.app/graphql/v2 \ | ||
| --header "Authorization: Bearer $RAILWAY_TOKEN" \ | ||
| --header 'Content-Type: application/json' \ | ||
| --data "{\"query\": \"{ environment(id: \\\"$RAILWAY_ENVIRONMENT_ID\\\") { serviceInstances { edges { node { source { image } } } } } }\"}") | ||
|
|
||
| if [ $? -ne 0 ]; then | ||
| echo "Error: curl command failed. Output:" | ||
| echo "$RAILWAY_SERVICES_OUTPUT" | ||
| exit 1 | ||
| fi | ||
| --fail \ | ||
| --url "$INDEXING_STATUS_URL" | \ | ||
| jq -r '.stackInfo.ensIndexer.versionInfo.ensIndexer') |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Bound the ENSNode indexing-status request.
curl --fail still has no connection or total timeout, so a stalled endpoint can hang this production promotion job until the workflow timeout. Add bounded timeouts and a small retry budget.
Proposed fix
ENSNODE_VERSION=$(curl \
--silent \
--show-error \
--fail \
+ --connect-timeout 10 \
+ --max-time 30 \
+ --retry 3 \
+ --retry-delay 2 \
+ --retry-connrefused \
--url "$INDEXING_STATUS_URL" | \
jq -r '.stackInfo.ensIndexer.versionInfo.ensIndexer')📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # first, get the deployed ENSNode version from the ENSApi indexing-status endpoint | |
| INDEXING_STATUS_URL="https://api.alpha.${ENSNODE_ENVIRONMENT}.ensnode.io/api/indexing-status" | |
| ENSNODE_VERSION=$(curl \ | |
| --silent \ | |
| --show-error \ | |
| --url https://backboard.railway.app/graphql/v2 \ | |
| --header "Authorization: Bearer $RAILWAY_TOKEN" \ | |
| --header 'Content-Type: application/json' \ | |
| --data "{\"query\": \"{ environment(id: \\\"$RAILWAY_ENVIRONMENT_ID\\\") { serviceInstances { edges { node { source { image } } } } } }\"}") | |
| if [ $? -ne 0 ]; then | |
| echo "Error: curl command failed. Output:" | |
| echo "$RAILWAY_SERVICES_OUTPUT" | |
| exit 1 | |
| fi | |
| --fail \ | |
| --url "$INDEXING_STATUS_URL" | \ | |
| jq -r '.stackInfo.ensIndexer.versionInfo.ensIndexer') | |
| # first, get the deployed ENSNode version from the ENSApi indexing-status endpoint | |
| INDEXING_STATUS_URL="https://api.alpha.${ENSNODE_ENVIRONMENT}.ensnode.io/api/indexing-status" | |
| ENSNODE_VERSION=$(curl \ | |
| --silent \ | |
| --show-error \ | |
| --fail \ | |
| --connect-timeout 10 \ | |
| --max-time 30 \ | |
| --retry 3 \ | |
| --retry-delay 2 \ | |
| --retry-connrefused \ | |
| --url "$INDEXING_STATUS_URL" | \ | |
| jq -r '.stackInfo.ensIndexer.versionInfo.ensIndexer') |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/actions/promote_vercel_deployment/promote_vercel_deployment.sh
around lines 41 - 48, The ENSNode indexing-status fetch in
promote_vercel_deployment.sh is unbounded and can hang the promotion job if the
endpoint stalls. Update the curl call used to populate ENSNODE_VERSION with
explicit connection and total timeouts, plus a small retry budget, while keeping
the existing INDEXING_STATUS_URL and jq parsing flow intact. Use the existing
promote_vercel_deployment.sh request block as the place to apply the
timeout/retry settings so the workflow fails fast instead of waiting for the
full job timeout.
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| target: | ||
| description: "New ENSDb Playground environment" | ||
| required: true | ||
| type: choice | ||
| options: | ||
| - green | ||
| - blue | ||
|
|
||
| jobs: | ||
| switch-environment: | ||
| # NOTE: this needs to run on GH runner because of some obscure skopeo permissions thing | ||
| runs-on: ubuntu-latest |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
Serialize ENSDb Playground environment switches.
This workflow mutates a single Traefik production routing key; overlapping manual dispatches can race and leave routing determined by the last Redis write, not operator intent. Add a workflow-level deployment lock.
Proposed fix
on:
workflow_dispatch:
inputs:
target:
description: "New ENSDb Playground environment"
required: true
type: choice
options:
- green
- blue
+
+concurrency:
+ group: deploy-switch-ensdb-playground-environment
+ cancel-in-progress: false
jobs:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| on: | |
| workflow_dispatch: | |
| inputs: | |
| target: | |
| description: "New ENSDb Playground environment" | |
| required: true | |
| type: choice | |
| options: | |
| - green | |
| - blue | |
| jobs: | |
| switch-environment: | |
| # NOTE: this needs to run on GH runner because of some obscure skopeo permissions thing | |
| runs-on: ubuntu-latest | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| target: | |
| description: "New ENSDb Playground environment" | |
| required: true | |
| type: choice | |
| options: | |
| - green | |
| - blue | |
| concurrency: | |
| group: deploy-switch-ensdb-playground-environment | |
| cancel-in-progress: false | |
| jobs: | |
| switch-environment: | |
| # NOTE: this needs to run on GH runner because of some obscure skopeo permissions thing | |
| runs-on: ubuntu-latest |
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 6-15: insufficient job-level concurrency limits (concurrency-limits): workflow is missing concurrency setting
(concurrency-limits)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/deploy_switch_ensdb_playground_environment.yml around
lines 6 - 20, The manual environment switch workflow can race because multiple
dispatches of switch-environment mutate the same Traefik routing key at once.
Add a workflow-level deployment lock using the workflow’s concurrency controls
so only one run can execute or queue at a time, and apply it to the
deploy_switch_ensdb_playground_environment workflow around the existing
workflow_dispatch/job setup.
Source: Linters/SAST tools
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 1 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ref_json="$(gh api repos/actions/checkout/git/ref/tags/v6)"
sha="$(jq -r '.object.sha' <<<"$ref_json")"
type="$(jq -r '.object.type' <<<"$ref_json")"
if [ "$type" = "tag" ]; then
gh api "repos/actions/checkout/git/tags/$sha" --jq '.object.sha'
else
echo "$sha"
fiRepository: namehash/ensnode
Length of output: 1984
🌐 Web query:
actions/checkout persist-credentials default documentation hash pinning recommendation
💡 Result:
The actions/checkout action, maintained by GitHub, includes a persist-credentials input that controls whether authentication credentials (the GitHub token or a provided SSH key) are configured in the local Git configuration [1][2]. Default Behavior and Recommendation: The default value for persist-credentials is true [3][4]. When enabled, the action configures the runner's local Git environment with credentials, which allows subsequent steps in the same job to execute authenticated Git commands [1][5]. Security experts and industry guidance, including the OWASP GitHub Actions Security Cheat Sheet, strongly recommend setting persist-credentials: false unless your workflow explicitly requires authenticated Git operations [6][7]. This practice is recommended to minimize the attack surface by preventing credentials from being stored in the environment, thereby reducing the risk of accidental exposure if the workflow is compromised [6][7]. Action Versioning and Hash Pinning: Regarding hash pinning, it is a recommended security best practice to pin all GitHub Actions to a specific commit SHA rather than using tags (like v4) [6][7]. This ensures that your workflow consistently runs the exact same code, protecting against potential supply chain attacks where a tag might be updated to point to malicious code [7]. Example Configuration: To implement these security recommendations, use the following pattern in your workflow YAML: - uses: actions/checkout@<FULL_COMMIT_SHA> with: persist-credentials: false Replace <FULL_COMMIT_SHA> with the specific 40-character commit hash of the version you intend to use [6][7].
Citations:
- 1: https://github.com/actions/checkout/blob/main/README.md
- 2: https://github.com/actions/checkout/blob/v4/README.md
- 3: https://github.com/actions/checkout/blob/34e114876b0b11c390a56381ad16ebd13914f8d5/action.yml
- 4: https://github.com/actions/checkout/blob/v4/action.yml
- 5: https://github.com/actions/checkout/tree/v4
- 6: https://cheatsheetseries.owasp.org/cheatsheets/GitHub_Actions_Security_Cheat_Sheet.html
- 7: https://www.wiz.io/blog/github-actions-security-guide
Harden the checkout step.
actions/checkout@v6 is tag-pinned instead of SHA-pinned, and persist-credentials defaults to true, which leaves GITHUB_TOKEN in the local git config. Pin to a full commit SHA and set persist-credentials: false unless later steps need authenticated git access.
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 27-30: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 28-28: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/deploy_switch_ensdb_playground_environment.yml around
lines 27 - 30, The Checkout repository step in the deploy workflow needs
hardening: `actions/checkout` is currently tag-pinned and leaves credentials in
git config by default. Update the `Checkout repository` step to use a full
commit SHA for `actions/checkout` and set `persist-credentials` to false unless
later steps in the workflow require authenticated git access.
Source: Linters/SAST tools
| - name: Send Slack Notification | ||
| uses: ./.github/actions/send_slack_notification |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== Workflow snippet ==\n'
sed -n '45,65p' .github/workflows/deploy_switch_ensdb_playground_environment.yml
printf '\n== Action metadata ==\n'
sed -n '1,80p' .github/actions/send_slack_notification/action.yml
printf '\n== References to send_slack_notification ==\n'
rg -n "send_slack_notification|actionlint|description:" .github -SRepository: namehash/ensnode
Length of output: 1955
🌐 Web query:
GitHub Actions action.yml top-level description required local action metadata actionlint local action missing description
💡 Result:
In GitHub Actions, the description field in the action.yml metadata file is required [1][2]. The official GitHub Actions metadata syntax documentation explicitly lists description as a required top-level key for defining an action [1][3]. Regarding actionlint, this static analysis tool enforces metadata requirements for local actions. Since version 1.7.0, actionlint has included checks for the action metadata file (action.yml or action.yaml) [4]. If the top-level description field is missing from your action.yml file, actionlint will report an error (e.g., 'description' section is missing) [4]. Because actionlint primarily focuses on checking workflow files rather than independently validating action.yml files in isolation, you may need to ensure your action is being referenced in a workflow or test file that actionlint scans, or verify your linting configuration, to see the error reported [4].
Citations:
- 1: https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax
- 2: https://docs.github.com/en/enterprise-server@3.12/actions/creating-actions/metadata-syntax-for-github-actions
- 3: https://github.com/github/docs/blob/main/content/actions/reference/workflows-and-actions/metadata-syntax.md
- 4: https://github.com/rhysd/actionlint/releases/tag/v1.7.0
Add the missing description in .github/actions/send_slack_notification/action.yml
actionlint treats local actions without a top-level description as invalid, so this workflow step can fail linting until the action metadata is updated.
🧰 Tools
🪛 actionlint (1.7.12)
[error] 56-56: description is required in metadata of "Send Slack notification" action at "/home/jailuser/git/.github/actions/send_slack_notification/action.yml"
(action)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/deploy_switch_ensdb_playground_environment.yml around
lines 55 - 56, The local action referenced by Send Slack Notification is missing
required metadata, causing actionlint to reject the workflow. Update
.github/actions/send_slack_notification/action.yml to add a top-level
description field alongside the existing action metadata so the uses step for
send_slack_notification is lint-valid.
Source: Linters/SAST tools
Lite PR
Tip: Review docs on the ENSNode PR process
Summary
promote_vercel_deployment.shscript has been updated to allow sourcing the ENSNode version independently from the platform (Railway, Render) that the current production deployment runs on.Why
Testing
Notes for Reviewer (Optional)
Pre-Review Checklist (Blocking)