Skip to content

ci: add GHA and license linters#95

Merged
MegaRedHand merged 2 commits intomainfrom
ci/add-linters
Feb 5, 2026
Merged

ci: add GHA and license linters#95
MegaRedHand merged 2 commits intomainfrom
ci/add-linters

Conversation

@MegaRedHand
Copy link
Collaborator

@MegaRedHand MegaRedHand commented Feb 5, 2026

This PR adds the GHA and License linters used in ethrex

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

🤖 Kimi Code Review

Review Summary

The PR adds two GitHub Actions workflows for linting. While the intent is good, there are several issues that need to be addressed:

Critical Issues

  1. Invalid GitHub Actions version (.github/workflows/pr_lint_gha.yaml:23 and .github/workflows/pr_lint_license.yaml:23)

    • actions/checkout@v6 does not exist. The latest version is v4.
    • This will cause the workflows to fail immediately.
  2. Security vulnerability in actionlint installation (.github/workflows/pr_lint_gha.yaml:26-28)

    • Using bash <(curl -s ...) without verification is dangerous
    • No checksum verification for the downloaded binary
    • Suggest using the official actionlint action or at least verify the download

Logic Issues

  1. Incorrect license check logic (.github/workflows/pr_lint_license.yaml:38-44)
    • The cargo metadata query is checking .license != "LICENSE" which is incorrect
    • The license field in Cargo.toml should be a license identifier (e.g., "MIT", "Apache-2.0"), not a filename
    • The check should verify that packages have a license specified, not that they reference "LICENSE"

Minor Issues

  1. Missing error handling (.github/workflows/pr_lint_license.yaml:35-36)

    • The cargo metadata command could fail, but the script continues with 2>/dev/null
    • Should check the exit status before processing
  2. Workflow naming (.github/workflows/pr_lint_gha.yaml:1)

    • "GitHub Actions" is too generic for a workflow name
    • Suggest "Lint GitHub Actions" or similar

Suggested Fixes

# For pr_lint_gha.yaml
- uses: actions/checkout@v4  # Fix version
- name: Run actionlint
  uses: raven-actions/actionlint@v2  # Use official action instead of curl

# For pr_lint_license.yaml
- uses: actions/checkout@v4  # Fix version
- name: Check all packages have license
  run: |
    if ! OUTPUT=$(cargo metadata --format-version 1 --no-deps); then
      echo "::error::Failed to get cargo metadata"
      exit 1
    fi
    
    MISSING=$(echo "$OUTPUT" | jq -r '.packages[] | select(.license == null) | .name')
    # ... rest of the logic

The workflows need these fixes before they can be safely merged.


Automated review by Kimi (Moonshot AI) · custom prompt

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

🤖 Codex Code Review

Only workflow changes in this PR; no consensus‑layer or Rust code touched.

Findings

  • actions/checkout@v6 does not exist; the latest stable major is v4. This will fail the workflow. Update both workflows.
    Ref: .github/workflows/pr_lint_gha.yaml:19, .github/workflows/pr_lint_license.yaml:23
  • The license check expects license = "LICENSE" in Cargo.toml, which is not a valid SPDX expression. The canonical Cargo field for a file is license-file = "LICENSE" or an SPDX license string in license. This workflow will flag valid packages as failures.
    Ref: .github/workflows/pr_lint_license.yaml:34-44
  • cargo metadata is invoked without installing Rust; ubuntu-latest does not include cargo by default. The job will fail unless Rust is installed. Add a Rust toolchain setup step.
    Ref: .github/workflows/pr_lint_license.yaml:31-44
  • jq is used but not guaranteed present; ubuntu-latest typically has it, but this is not guaranteed. If you need it, install jq explicitly or replace with a tool that ships with Rust (e.g., cargo metadata --format-version 1 --no-deps + rustc tool/python).
    Ref: .github/workflows/pr_lint_license.yaml:31-33

If you want, I can propose a corrected workflow snippet (using actions/checkout@v4, actions-rs/toolchain, and license-file checks).


Automated review by OpenAI Codex · custom prompt

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

🤖 Claude Code Review

Perfect! Now I have all the information I need to provide a comprehensive review. Let me compile the findings:

PR Review: CI - Add GHA and License Linters

Overview

This PR adds two GitHub Actions workflows for linting: one for validating GitHub Actions syntax and one for enforcing license consistency across Cargo packages.

Issues Found

🔴 Critical: License Check Will Fail

File: .github/workflows/pr_lint_license.yaml:36-37

The license check workflow will fail immediately when run because the main ethlambda package (in /bin/ethlambda/Cargo.toml) does not have a license field:

# Current state:
$ cargo metadata --format-version 1 --no-deps | jq '.packages[] | {name, license}'
{
  "name": "ethlambda",
  "license": null  # ← This will cause the workflow to fail
}

All workspace crates inherit license = "LICENSE" from workspace.package, but the main binary crate at bin/ethlambda/Cargo.toml doesn't inherit this field.

Fix Required: Add license.workspace = true to bin/ethlambda/Cargo.toml:

[package]
name = "ethlambda"
version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true  # ← Add this line

🟡 Minor: Process Substitution Security Concern

File: .github/workflows/pr_lint_gha.yaml:26

The workflow uses bash <(curl -s ...) which pipes remote script directly to bash. While this is the official installation method from actionlint's repository, it presents a supply chain risk for a consensus client.

Recommendation: Consider these alternatives:

  1. Pin to a specific actionlint release and verify checksum
  2. Use a pre-installed actionlint action from the marketplace (e.g., reviewdog/action-actionlint)
  3. Cache the binary after first download to avoid repeated remote fetches

For a blockchain consensus client where security is paramount, option 1 or 2 would be preferable.

📝 Style: Minor Shell Script Improvements

File: .github/workflows/pr_lint_license.yaml:36

The jq filter select(.license != "LICENSE") will also match packages where .license is null. This is actually desired behavior (as we saw with ethlambda), but the logic could be more explicit:

# Current (works but implicit):
jq -r '.packages[] | select(.license != "LICENSE") | .name'

# More explicit alternative:
jq -r '.packages[] | select(.license == null or .license != "LICENSE") | .name'

Current approach is fine since null != "LICENSE" evaluates to true in jq, but the second form is clearer about intent.

Positive Aspects ✅

  1. Good workflow structure: Both workflows follow GitHub Actions best practices with proper permissions, concurrency groups, and path-based triggers
  2. Consistent patterns: Matches existing workflows (e.g., docker_publish.yaml) in using actions/checkout@v6, concurrency groups, etc.
  3. Useful automation: Catching license drift and GHA syntax errors in CI is valuable
  4. Appropriate triggers: Both workflows correctly trigger on relevant file changes and support manual dispatch

Recommendation

Do not merge until the license field issue is fixed in bin/ethlambda/Cargo.toml. The workflow will fail on the first run, blocking future PRs unnecessarily.

Consider addressing the security concern around actionlint installation for a production consensus client, though this is lower priority.


Summary

  • 🔴 BLOCKING: Main package missing license field - will cause immediate CI failure
  • 🟡 RECOMMENDED: Consider more secure actionlint installation method
  • GOOD: Workflow structure, patterns, and automation goals

Automated review by Claude (Anthropic) · custom prompt

@MegaRedHand MegaRedHand marked this pull request as ready for review February 5, 2026 20:14
@github-actions
Copy link

github-actions bot commented Feb 5, 2026

🤖 Kimi Code Review

Review Summary

This PR adds two GitHub Actions workflows for linting GitHub Actions files and checking license compliance. The changes are straightforward CI/CD improvements with no consensus-layer impact.

Issues Found

1. Critical: Incorrect actions/checkout version (.github/workflows/pr_lint_gha.yaml:23, .github/workflows/pr_lint_license.yaml:23)

Both workflows use actions/checkout@v6 but this version doesn't exist. The latest stable version is v4. This will cause the workflows to fail.

Fix:

- uses: actions/checkout@v4

2. Security: Unverified script execution (.github/workflows/pr_lint_gha.yaml:26-28)

The actionlint installation uses bash <(curl ...) which downloads and executes unverified code. This is a security risk for a blockchain project.

Fix: Use a pinned version with checksum verification:

- name: Install actionlint
  run: |
    curl -sL -o actionlint.tar.gz https://github.com/rhysd/actionlint/releases/download/v1.6.27/actionlint_1.6.27_linux_amd64.tar.gz
    echo "c2f6a4b78a53292d019d3b94e9e5f6b0b202b6d9f3f9c9e7b5a3e8f8e8e8e8e8  actionlint.tar.gz" | sha256sum -c -
    tar -xzf actionlint.tar.gz actionlint
    chmod +x actionlint

3. Logic Error: License check misunderstanding (.github/workflows/pr_lint_license.yaml:38-47)

The license check uses .license != "LICENSE" which checks the SPDX license identifier, not whether the package references the LICENSE file. The correct field is .license_file.

Fix:

MISSING=$(cargo metadata --format-version 1 --no-deps 2>/dev/null | \
  jq -r '.packages[] | select(.license_file == null) | .name')

4. Minor: Inconsistent workflow naming (.github/workflows/pr_lint_gha.yaml:1)

The workflow name "GitHub Actions" is too generic. Consider "Lint GitHub Actions" for clarity.

5. Minor: Missing error handling (.github/workflows/pr_lint_license.yaml:35-36)

The cargo metadata command could fail, but the script continues. Add error handling:

if ! METADATA=$(cargo metadata --format-version 1 --no-deps 2>/dev/null); then
  echo "::error::Failed to get cargo metadata"
  exit 1
fi

Positive Notes

  • Good use of concurrency groups to prevent duplicate runs
  • Appropriate use of path filters to avoid unnecessary workflow runs
  • Proper permission scoping with contents: read

The PR is generally well-structured but needs the above fixes before merging.


Automated review by Kimi (Moonshot AI) · custom prompt

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

🤖 Codex Code Review

Findings (ordered by severity)

  • Critical: Cargo manifest license validation is incorrect. The workflow enforces license = "LICENSE" in Cargo.toml, but Cargo expects an SPDX identifier in license and a file path in license-file. This will fail for any correct Rust crate and may mask real licensing errors. Update the check to validate license-file = "LICENSE" (or allow either license SPDX or license-file) and adjust the jq filter accordingly. /.github/workflows/pr_lint_license.yaml:31-41
  • High: The license workflow uses cargo metadata but does not install Rust toolchain. On ubuntu-latest this can fail if Rust isn’t preinstalled, making the workflow flaky. Add actions/setup-rust or dtolnay/rust-toolchain before running cargo. /.github/workflows/pr_lint_license.yaml:27-41
  • Medium: actions/checkout@v6 does not exist (current major is v4). This will break both workflows. Use actions/checkout@v4. /.github/workflows/pr_lint_gha.yaml:20, /.github/workflows/pr_lint_license.yaml:21
  • Low/Security: Downloading actionlint via curl+bash without pinning a version or checksum is a supply-chain risk. Prefer a pinned release URL with checksum verification or a published action. /.github/workflows/pr_lint_gha.yaml:23-26

Notes

  • The only Rust change is license.workspace = true in bin/ethlambda/Cargo.toml and it’s fine once workspace license is correctly configured. bin/ethlambda/Cargo.toml:3-7
  • No consensus-layer code changes in this PR; no fork-choice, state transition, or SSZ review needed here.

If you want, I can propose an updated workflow snippet for the license check.


Automated review by OpenAI Codex · custom prompt

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

🤖 Claude Code Review

Now I have a complete picture. Let me create a comprehensive review:

PR Review: ci: add GHA and license linters

Overview

This PR adds two CI linters from ethrex: one for GitHub Actions workflows and one for license checking. The implementation is clean and focused.

✅ Positive Findings

  1. Follows existing patterns: Matches the style and structure of the existing ci.yml workflow (permissions, concurrency groups, checkout action version)

  2. Proper concurrency handling: Both workflows use cancel-in-progress: true with appropriate groups to avoid wasted CI runs

  3. Selective path triggers: Smart path filtering means these checks only run when relevant files change:

    • GHA linter: only on .github/**.yaml and .github/**.yml changes
    • License linter: only on **/Cargo.toml, LICENSE*, or the workflow itself
  4. Minimal permissions: Both use permissions: contents: read following least-privilege principle

🔍 Issues Found

Critical: License field semantics (.github/workflows/pr_lint_license.yaml:37)

Problem: The license check expects license = "LICENSE" but this is incorrect Cargo.toml semantics.

jq -r '.packages[] | select(.license != "LICENSE") | .name')

The license field in Cargo.toml should contain an SPDX license identifier (e.g., "MIT", "Apache-2.0") or a license file path using license-file = "LICENSE". Using license = "LICENSE" is non-standard.

Current state: The workspace Cargo.toml at line 21 has:

license = "LICENSE"

This works but violates Cargo conventions. The correct approach is either:

  • Option A: Use license-file = "LICENSE" (if custom license)
  • Option B: Use license = "MIT" (or appropriate SPDX ID) + keep LICENSE file

Impact:

  • Published crates won't display properly on crates.io
  • cargo metadata consumers expect SPDX identifiers
  • Other tools may not recognize the license correctly

Recommendation: Either fix the workspace Cargo.toml to use proper semantics OR update the lint check to use license-file instead of license. If this is intentionally using a non-standard approach for this project, add a comment explaining why.

Minor: Shell expansion issue (.github/workflows/pr_lint_gha.yaml:26)

run: bash <(curl -s https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)

The -ignore SC2086 flag on line 29 suppresses shellcheck warnings about unquoted variable expansion, but this specific download command doesn't need that flag. The flag is likely meant for actionlint's analysis of the repository's workflows.

Verification needed: Does this specific project have workflows that trigger SC2086 warnings? If not, consider removing the ignore flag or being more specific about which files need it.

Documentation: Missing context

The PR description says these linters are "used in ethrex" but doesn't explain:

  • What problems they solve
  • Why ethlambda needs them
  • What the license = "LICENSE" pattern means for this project

🎯 Testing Verification

The license checker will currently pass because all packages already have license.workspace = true pointing to the workspace-level license = "LICENSE". However, this is testing the wrong thing—it's validating non-standard Cargo semantics.

📋 Recommendations

  1. High priority: Clarify the license field approach. Either:

    • Fix the workspace to use license-file = "LICENSE" and update the lint
    • Or use a proper SPDX identifier if applicable
    • Or document why license = "LICENSE" is intentionally used
  2. Medium priority: Verify the -ignore SC2086 flag is needed for your actual workflows

  3. Low priority: Add a comment to the license lint explaining the expected pattern

Verdict

Request changes due to the license field semantics issue. The workflows are well-structured and will function, but they're checking for a non-standard Cargo pattern that could cause issues with the Rust ecosystem tooling.


Automated review by Claude (Anthropic) · custom prompt

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 5, 2026

Greptile Overview

Greptile Summary

This PR adds two CI linting workflows from the ethrex project: one for validating GitHub Actions workflow files using actionlint, and one for ensuring all Cargo packages properly reference the LICENSE file. The bin/ethlambda/Cargo.toml was updated to include license.workspace = true to align with other workspace packages.

Key Changes:

  • Added pr_lint_gha.yaml workflow to lint GitHub Actions files with actionlint (ignoring SC2086 shellcheck warning)
  • Added pr_lint_license.yaml workflow to verify LICENSE file exists and all packages reference it
  • Updated bin/ethlambda/Cargo.toml to include license field from workspace

Issues Found:

  • The GHA linter uses an insecure installation method (curl | bash) without integrity verification - should use official GitHub Action instead

Confidence Score: 3/5

  • This PR can be merged but has a security issue in the GHA workflow that should be addressed
  • The workflows add useful CI checks and the Cargo.toml change is correct, but the insecure curl-to-bash installation method in the GHA linter is a security risk that reduces confidence
  • .github/workflows/pr_lint_gha.yaml needs attention due to the insecure installation method on line 26

Important Files Changed

Filename Overview
.github/workflows/pr_lint_gha.yaml added GHA workflow linter with actionlint, but uses insecure curl-to-bash installation method
.github/workflows/pr_lint_license.yaml added license checking workflow that validates LICENSE file exists and all packages reference it consistently
bin/ethlambda/Cargo.toml added license.workspace = true to align with other workspace packages

Sequence Diagram

sequenceDiagram
    participant Dev as Developer
    participant PR as Pull Request
    participant GHA as GitHub Actions (pr_lint_gha)
    participant License as License Check (pr_lint_license)
    participant Repo as Repository

    Dev->>PR: Create/Update PR with workflow or Cargo.toml changes
    
    alt Workflow files changed
        PR->>GHA: Trigger pr_lint_gha workflow
        GHA->>GHA: Download actionlint via curl
        GHA->>Repo: Check out code
        GHA->>Repo: Run actionlint on .github/**/*.yaml
        GHA->>PR: Report linting results
    end
    
    alt Cargo.toml or LICENSE files changed
        PR->>License: Trigger pr_lint_license workflow
        License->>Repo: Check out code
        License->>Repo: Verify LICENSE file exists
        License->>Repo: Run cargo metadata
        License->>Repo: Check all packages have license="LICENSE"
        License->>PR: Report validation results
    end
    
    PR->>Dev: Show CI status
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@MegaRedHand MegaRedHand merged commit 242a9d2 into main Feb 5, 2026
9 checks passed
@MegaRedHand MegaRedHand deleted the ci/add-linters branch February 5, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants