From 1b6ada06faec849778415d74ca5835b80a64bb53 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Fri, 2 Oct 2026 10:43:18 +0200 Subject: [PATCH 1/4] ci: enforce formatting with prettier --- .mise/locks/npm-prettier/3.9.8/aube-lock.yaml | 24 +++++++++++++++++++ .mise/locks/npm-prettier/3.9.8/package.json | 7 ++++++ .prettierignore | 5 ++++ .prettierrc.json | 3 +++ CONTRIBUTING.md | 16 ++++++++++--- mise.lock | 6 +++++ mise.toml | 13 +++++++++- 7 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 .mise/locks/npm-prettier/3.9.8/aube-lock.yaml create mode 100644 .mise/locks/npm-prettier/3.9.8/package.json create mode 100644 .prettierignore create mode 100644 .prettierrc.json diff --git a/.mise/locks/npm-prettier/3.9.8/aube-lock.yaml b/.mise/locks/npm-prettier/3.9.8/aube-lock.yaml new file mode 100644 index 0000000..d6a5391 --- /dev/null +++ b/.mise/locks/npm-prettier/3.9.8/aube-lock.yaml @@ -0,0 +1,24 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + prettier: + specifier: 3.9.8 + version: 3.9.8 + +packages: + + prettier@3.9.8: + resolution: {integrity: sha512-WRFq3Wn3WId7LLROfMLdH7xaFr2jR62wU8nLO6rQUOLOxNZUviyJQs1M0iIhLexSFy+L+w0ch66wtoO2jRjG0A==} + engines: {node: '>=14'} + hasBin: true + +snapshots: + + prettier@3.9.8: {} diff --git a/.mise/locks/npm-prettier/3.9.8/package.json b/.mise/locks/npm-prettier/3.9.8/package.json new file mode 100644 index 0000000..402cf9e --- /dev/null +++ b/.mise/locks/npm-prettier/3.9.8/package.json @@ -0,0 +1,7 @@ +{ + "name": "mise-npm-install", + "private": true, + "dependencies": { + "prettier": "3.9.8" + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..97beabb --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +# generated files +## release-please +*/CHANGELOG.md +## mise +.mise/ \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..d2504b4 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "proseWrap": "never" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e8909c..4cbd95e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,16 +7,26 @@ Each shared reusable workflow is backed by a Component directory `/` that After editing any `.github/workflows/.yml` for a workflow listed in `release-please-config.json`, run: ```sh -bash scripts/compute-workflow-sha256.sh +mise run update-checksums ``` -This regenerates `/workflow-sha256`, a checksum of the workflow file. Commit the resulting diff alongside your workflow change β€” this is what makes the change visible to release-please for that Component. +This formats the repository (see [Formatting](#formatting)), then runs `scripts/compute-workflow-sha256.sh`, which regenerates `/workflow-sha256`, a checksum of the workflow file. Commit the resulting diff alongside your workflow change β€” this is what makes the change visible to release-please for that Component. CI enforces this on every pull request via `bash scripts/compute-workflow-sha256.sh --check`, which fails if any `workflow-sha256` file is out of date. +## Formatting + +Files are formatted with [Prettier](https://prettier.io), using its default settings. Generated files (release-please changelogs, mise files) are excluded via `.prettierignore`. Format the repository with: + +```sh +mise run format +``` + +Formatting can rewrite workflow files, which changes their checksum. After editing a workflow, run `mise run update-checksums` instead of `mise run format` alone, so `workflow-sha256` files are computed from the formatted content. + ## Linting -Workflows are linted with [actionlint](https://github.com/rhysd/actionlint), which also runs [shellcheck](https://github.com/koalaman/shellcheck) on inline `run:` scripts. Shell scripts committed to the repository (`*.sh`, e.g. under `scripts/`) are linted with shellcheck directly. Both tools are pinned in `mise.toml` and `mise.lock`. Install them with [mise](https://mise.jdx.dev): +Workflows are linted with [actionlint](https://github.com/rhysd/actionlint), which also runs [shellcheck](https://github.com/koalaman/shellcheck) on inline `run:` scripts. Shell scripts committed to the repository (`*.sh`, e.g. under `scripts/`) are linted with shellcheck directly. Formatting is checked with `prettier --check`. All tools are pinned in `mise.toml` and `mise.lock`. Install them with [mise](https://mise.jdx.dev): ```sh mise install --locked diff --git a/mise.lock b/mise.lock index c4d29c5..0faeacf 100644 --- a/mise.lock +++ b/mise.lock @@ -88,3 +88,9 @@ url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/2790 checksum = "sha256:8a4e35ab0b331c85d73567b12f2a444df187f483e5079ceffa6bda1faa2e740e" url = "https://github.com/koalaman/shellcheck/releases/download/v0.11.0/shellcheck-v0.11.0.zip" url_api = "https://api.github.com/repos/koalaman/shellcheck/releases/assets/279056944" + +[[tools."npm:prettier"]] +version = "3.9.8" +aube = { path = ".mise/locks/npm-prettier/3.9.8", digest = "sha256:5c76115168054cd13c6ad573ac7befc182bce737bc8bca3ed27b8287e2611eeb" } +backend = "npm:prettier" +specifiers = ["3.9.8"] diff --git a/mise.toml b/mise.toml index 8cd129b..55b72d8 100644 --- a/mise.toml +++ b/mise.toml @@ -5,6 +5,17 @@ lockfile = true [tools] "aqua:actionlint" = "1.7.12" "aqua:koalaman/shellcheck" = "0.11.0" +"npm:prettier" = "3.9.8" + +[tasks.format] +run = "prettier --write ." + +[tasks."update-checksums"] +run = "scripts/compute-workflow-sha256.sh" +depends = ["format"] + +[tasks."lint:format"] +run = "prettier --check ." [tasks."lint:actionlint"] run = "actionlint" @@ -14,4 +25,4 @@ shell = "bash -euo pipefail -c" run = "git ls-files -z --cached --others --exclude-standard '*.sh' | xargs -0 -r shellcheck" [tasks.lint] -depends = [ "lint:actionlint", "lint:shellcheck" ] +depends = [ "lint:format", "lint:actionlint", "lint:shellcheck" ] From 09c03a6e2ee588035dc5bf39ea0d4602d231b2de Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Fri, 2 Oct 2026 10:46:44 +0200 Subject: [PATCH 2/4] style: format project --- .github/workflows/docker-build-cloud.yml | 3 +- .github/workflows/docker-build.yml | 7 +- .github/workflows/docker-promote.yml | 4 +- .../workflows/propose-safe-multisig-tx.yml | 28 +++--- .github/workflows/rust-build.yml | 16 ++-- .../validate-release-please-config.yml | 12 +-- .github/workflows/verify-workflow-sha256.yml | 16 ++-- conventional-commits/README.md | 10 ++- docker-build-cloud/README.md | 39 ++++---- docker-build-cloud/workflow-sha256 | 2 +- docker-build/README.md | 66 +++++++------- docker-build/workflow-sha256 | 2 +- docker-promote/README.md | 11 ++- docker-promote/workflow-sha256 | 2 +- java-build/README.md | 89 +++++++------------ propose-safe-multisig-tx/README.md | 60 ++++++------- propose-safe-multisig-tx/src/env.ts | 4 +- propose-safe-multisig-tx/src/index.ts | 33 ++++--- propose-safe-multisig-tx/workflow-sha256 | 2 +- publish-npm/README.md | 60 ++++++------- release-please/README.md | 6 +- rust-build/README.md | 24 ++--- rust-build/workflow-sha256 | 2 +- 23 files changed, 240 insertions(+), 258 deletions(-) diff --git a/.github/workflows/docker-build-cloud.yml b/.github/workflows/docker-build-cloud.yml index 1927572..a14d8e2 100644 --- a/.github/workflows/docker-build-cloud.yml +++ b/.github/workflows/docker-build-cloud.yml @@ -28,7 +28,8 @@ on: default: "." type: string build-args: - description: "Docker build arguments (multiline format: KEY1=value1\nKEY2=value2)" + description: + "Docker build arguments (multiline format: KEY1=value1\nKEY2=value2)" default: "" type: string attest: diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 995fdac..141a1ad 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -4,7 +4,8 @@ on: workflow_call: inputs: build-args: - description: "Docker build arguments (multiline format: KEY1=value1\nKEY2=value2)" + description: + "Docker build arguments (multiline format: KEY1=value1\nKEY2=value2)" default: "" type: string image-name: @@ -149,8 +150,8 @@ jobs: context: ${{ inputs.context }} file: ${{ inputs.dockerfile }} platforms: ${{ inputs.platform }} - load: true # Make the image available on runner - push: false # Don't push yet, wait for security checks + load: true # Make the image available on runner + push: false # Don't push yet, wait for security checks tags: ${{ inputs.image-name }}:${{ inputs.image-tag }} - name: Run Trivy vulnerability scanner diff --git a/.github/workflows/docker-promote.yml b/.github/workflows/docker-promote.yml index 6ed0e38..39bcae6 100644 --- a/.github/workflows/docker-promote.yml +++ b/.github/workflows/docker-promote.yml @@ -214,8 +214,8 @@ jobs: image-ref: ${{ env.IMAGE }}@${{ steps.tested.outputs.digest }} format: table ignore-unfixed: true - vuln-type: 'os,library' - severity: 'CRITICAL,HIGH' + vuln-type: "os,library" + severity: "CRITICAL,HIGH" hide-progress: true exit-code: 1 # same scanner version as the CI build, so a finding here means the diff --git a/.github/workflows/propose-safe-multisig-tx.yml b/.github/workflows/propose-safe-multisig-tx.yml index 499b20c..97159b8 100644 --- a/.github/workflows/propose-safe-multisig-tx.yml +++ b/.github/workflows/propose-safe-multisig-tx.yml @@ -1,45 +1,45 @@ -name: 'Propose Safe Multisig Transaction' +name: "Propose Safe Multisig Transaction" on: workflow_call: inputs: safe-address: - description: 'Address of the Safe contract' + description: "Address of the Safe contract" required: true type: string transaction-to: - description: 'Target address of the transaction' + description: "Target address of the transaction" required: true type: string transaction-value: - description: 'Value to send in the transaction (in wei, default: 0)' + description: "Value to send in the transaction (in wei, default: 0)" required: false - default: '0' + default: "0" type: string transaction-data: - description: 'Transaction data/calldata' + description: "Transaction data/calldata" required: true type: string dry-run: - description: 'If true, validate and prepare the transaction without proposing it' + description: "If true, validate and prepare the transaction without proposing it" required: false default: false type: boolean secrets: rpc-url: - description: 'RPC URL for the blockchain network' + description: "RPC URL for the blockchain network" required: true safe-proposer-private-key: - description: 'Private key of the proposer wallet' + description: "Private key of the proposer wallet" required: true safe-api-key: - description: 'Safe API key for transaction service' + description: "Safe API key for transaction service" required: true outputs: tx-hash: - description: 'Hash of the Safe transaction' + description: "Hash of the Safe transaction" value: ${{ jobs.propose-transaction.outputs.tx-hash }} tx-details: - description: 'Created transaction details' + description: "Created transaction details" value: ${{ jobs.propose-transaction.outputs.tx-details }} jobs: @@ -48,7 +48,7 @@ jobs: outputs: tx-hash: ${{ steps.safe-transaction.outputs.tx-hash }} tx-details: ${{ steps.safe-transaction.outputs.tx-details }} - + steps: - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -58,7 +58,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: '22' + node-version: "22" - name: Install dependencies run: npm ci diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml index d5941bd..3170846 100644 --- a/.github/workflows/rust-build.yml +++ b/.github/workflows/rust-build.yml @@ -4,19 +4,19 @@ on: workflow_call: inputs: rust-version: - description: 'Rust version to use' - default: 'stable' + description: "Rust version to use" + default: "stable" type: string working-directory: - description: 'The directory to run jobs from' - default: '.' + description: "The directory to run jobs from" + default: "." type: string enable-cache: - description: 'Enable caching of dependencies' + description: "Enable caching of dependencies" default: true type: boolean publish-crates-io: - description: 'Publish package to crates.io' + description: "Publish package to crates.io" default: false type: boolean secrets: @@ -26,7 +26,7 @@ on: env: CARGO_TERM_COLOR: always CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - + jobs: build_and_publish: runs-on: ubuntu-latest @@ -80,7 +80,7 @@ jobs: - name: Check documentation working-directory: ${{ inputs.working-directory }} env: - RUSTDOCFLAGS: '-D warnings' + RUSTDOCFLAGS: "-D warnings" run: cargo doc --locked --no-deps --document-private-items - name: Validate package diff --git a/.github/workflows/validate-release-please-config.yml b/.github/workflows/validate-release-please-config.yml index dede66f..fdf1cf3 100644 --- a/.github/workflows/validate-release-please-config.yml +++ b/.github/workflows/validate-release-please-config.yml @@ -5,16 +5,16 @@ on: branches: - main paths: - - 'release-please-config.json' - - 'scripts/check-release-please-config.sh' - - '.github/workflows/validate-release-please-config.yml' + - "release-please-config.json" + - "scripts/check-release-please-config.sh" + - ".github/workflows/validate-release-please-config.yml" push: branches: - main paths: - - 'release-please-config.json' - - 'scripts/check-release-please-config.sh' - - '.github/workflows/validate-release-please-config.yml' + - "release-please-config.json" + - "scripts/check-release-please-config.sh" + - ".github/workflows/validate-release-please-config.yml" permissions: contents: read diff --git a/.github/workflows/verify-workflow-sha256.yml b/.github/workflows/verify-workflow-sha256.yml index d929740..a2d3ae6 100644 --- a/.github/workflows/verify-workflow-sha256.yml +++ b/.github/workflows/verify-workflow-sha256.yml @@ -5,18 +5,18 @@ on: branches: - main paths: - - '.github/workflows/*.yml' - - 'release-please-config.json' - - 'scripts/compute-workflow-sha256.sh' - - '**/workflow-sha256' + - ".github/workflows/*.yml" + - "release-please-config.json" + - "scripts/compute-workflow-sha256.sh" + - "**/workflow-sha256" push: branches: - main paths: - - '.github/workflows/*.yml' - - 'release-please-config.json' - - 'scripts/compute-workflow-sha256.sh' - - '**/workflow-sha256' + - ".github/workflows/*.yml" + - "release-please-config.json" + - "scripts/compute-workflow-sha256.sh" + - "**/workflow-sha256" permissions: contents: read diff --git a/conventional-commits/README.md b/conventional-commits/README.md index aa05f7b..62b861f 100644 --- a/conventional-commits/README.md +++ b/conventional-commits/README.md @@ -1,10 +1,13 @@ # πŸ“ Conventional Commits Workflow ## πŸ” Overview + This reusable GitHub Actions workflow validates that pull request titles follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. Conventional Commits provide a standardized format for commit messages, making it easier to generate changelogs, automate versioning, and understand the purpose of changes at a glance. By enforcing this standard, your repository maintains a clean and meaningful history that benefits both developers and automated tools. ## πŸ“š What are Conventional Commits? + Conventional Commits follow this structured format: + ``` [optional scope]: @@ -14,6 +17,7 @@ Conventional Commits follow this structured format: ``` ### 🏷️ Common Types Include: + - `✨ feat`: A new feature that adds functionality to your codebase - `πŸ› fix`: A bug fix that resolves an issue or problem - `πŸ“– docs`: Documentation changes or improvements @@ -25,6 +29,7 @@ Conventional Commits follow this structured format: - `πŸ”’ security`: Fixing security vulnerabilities or enhancing security ## 🌟 Benefits + - **πŸ“‹ Automated Changelog Generation**: Works seamlessly with tools like release-please to create detailed, organized changelogs without manual effort - **πŸ”’ Semantic Versioning Automation**: Helps determine version bumps based on commit types (major, minor, patch) following SemVer principles - **πŸ“Š Improved Repository History**: Makes your project history more readable, structured, and navigable for all team members @@ -37,10 +42,11 @@ Conventional Commits follow this structured format: ### πŸ” Secrets | Name | Description | Required | -|------|-------------|----------| +| --- | --- | --- | | `GITHUB_TOKEN` | GitHub token for authentication and PR interactions | Yes | ### πŸ›‘οΈ Permissions + The workflow requires `pull-requests: read` permission to access PR information and validate titles effectively. ## πŸ’» Example Usage @@ -63,6 +69,7 @@ jobs: ``` ## πŸ“‹ Implementation Notes + - πŸ”„ The workflow runs automatically when PRs are opened, edited, or reopened to ensure continuous validation - βœ… It validates the PR title against the Conventional Commits specification with comprehensive checks - πŸ’¬ If validation fails, the workflow writes detailed guidance on how to fix the title to the job summary @@ -70,6 +77,7 @@ jobs: - πŸš€ Helps maintain a high-quality repository that's ready for automated versioning and changelog generation ## πŸ› οΈ Troubleshooting + - If PR titles are consistently failing validation, consider providing team training on Conventional Commits - For complex projects, you may want to define custom scopes that align with your project's architecture - Remember that only the PR title needs to follow the convention, not every commit message (though that's also beneficial) diff --git a/docker-build-cloud/README.md b/docker-build-cloud/README.md index 2298bd9..09a4f6e 100644 --- a/docker-build-cloud/README.md +++ b/docker-build-cloud/README.md @@ -12,28 +12,27 @@ This reusable GitHub Actions workflow builds and pushes a multi-platform Docker - πŸš€ No QEMU emulation, no native ARM runners β€” DBC handles arch-specific builds - πŸ“œ Generates & signs a keyless SLSA build provenance attestation (optional) -> [!IMPORTANT] -> Requires a Docker Build Cloud subscription and a builder configured in your DockerHub organization. The DockerHub PAT must have the **Build** scope to authenticate to the cloud endpoint. - -## βš™οΈ Inputs - -| Name | Description | Required | Default | -| ------------------------ | --------------------------------------------------------------------------------- | -------- | -------------- | -| `attest` | Generate & sign a keyless SLSA build provenance attestation for the pushed image (requires caller permissions, see notes) | No | `false` | -| `build-args` | Docker build arguments (multiline format: `KEY1=value1\nKEY2=value2`) | No | `""` | -| `cloud-builder-endpoint` | Docker Build Cloud endpoint, format `/` | Yes | - | -| `context` | Path to Docker Build Context | No | `"."` | -| `dockerfile` | Path to the Dockerfile (e.g. `'./Dockerfile'`, `'./docker/Dockerfile'`) | No | `"Dockerfile"` | -| `image-name` | Name of Docker Image, fully qualified (e.g. `iexechub/my-image`) | Yes | - | -| `image-tag` | Tag to apply to the built image (e.g. `1.0.0`, no v prefix) | Yes | - | -| `platforms` | Comma-separated build platforms (e.g. `linux/amd64,linux/arm64`) | Yes | - | +> [!IMPORTANT] Requires a Docker Build Cloud subscription and a builder configured in your DockerHub organization. The DockerHub PAT must have the **Build** scope to authenticate to the cloud endpoint. + +## βš™οΈ Inputs + +| Name | Description | Required | Default | +| --- | --- | --- | --- | +| `attest` | Generate & sign a keyless SLSA build provenance attestation for the pushed image (requires caller permissions, see notes) | No | `false` | +| `build-args` | Docker build arguments (multiline format: `KEY1=value1\nKEY2=value2`) | No | `""` | +| `cloud-builder-endpoint` | Docker Build Cloud endpoint, format `/` | Yes | - | +| `context` | Path to Docker Build Context | No | `"."` | +| `dockerfile` | Path to the Dockerfile (e.g. `'./Dockerfile'`, `'./docker/Dockerfile'`) | No | `"Dockerfile"` | +| `image-name` | Name of Docker Image, fully qualified (e.g. `iexechub/my-image`) | Yes | - | +| `image-tag` | Tag to apply to the built image (e.g. `1.0.0`, no v prefix) | Yes | - | +| `platforms` | Comma-separated build platforms (e.g. `linux/amd64,linux/arm64`) | Yes | - | ## πŸ” Secrets -| Name | Description | Required | -| -------------------- | ------------------------------------------------------------------------------------------ | -------- | -| `dockerhub-username` | Username for Docker Hub authentication | Yes | -| `dockerhub-password` | Personal Access Token for Docker Hub with the **Build** scope (needed for DBC endpoint) | Yes | +| Name | Description | Required | +| --- | --- | --- | +| `dockerhub-username` | Username for Docker Hub authentication | Yes | +| `dockerhub-password` | Personal Access Token for Docker Hub with the **Build** scope (needed for DBC endpoint) | Yes | ## πŸ’» Example Usage @@ -43,7 +42,7 @@ name: Build and Push Release Image on: push: tags: - - 'v*.*.*' + - "v*.*.*" jobs: build-multiplatform: diff --git a/docker-build-cloud/workflow-sha256 b/docker-build-cloud/workflow-sha256 index a6e0c67..2135527 100644 --- a/docker-build-cloud/workflow-sha256 +++ b/docker-build-cloud/workflow-sha256 @@ -1 +1 @@ -9534ee4ca0e3ac583e44e73291978c1f83349585535e39fe1fe4804f651baee4 +43e170deab62e55ddba84fe208e8a0370f7ea1f3fd1cd8447c66836b7f926cbd diff --git a/docker-build/README.md b/docker-build/README.md index 86e090e..694d463 100644 --- a/docker-build/README.md +++ b/docker-build/README.md @@ -2,9 +2,7 @@ ## πŸ” Overview -This reusable GitHub Actions workflow automates the process of building and pushing Docker images to a Docker Registry. -It simplifies the Docker build process in your CI/CD pipeline by handling authentication, building, and tagging in a standardized way. -Perfect for teams looking to streamline their containerization workflow with minimal configuration. +This reusable GitHub Actions workflow automates the process of building and pushing Docker images to a Docker Registry. It simplifies the Docker build process in your CI/CD pipeline by handling authentication, building, and tagging in a standardized way. Perfect for teams looking to streamline their containerization workflow with minimal configuration. ## ✨ Features @@ -19,44 +17,42 @@ Perfect for teams looking to streamline their containerization workflow with min - πŸ“¦ Supports AMD64 and ARM64 platforms (one per workflow run) - πŸ“₯ Optionally pulls a build artifact from an earlier job into the build context, so a compiled binary or jar can be built once and copied into the image -> [!IMPORTANT] -> Due to a limitation on Trivy analysis, the workflow targets a single platform. -> A workflow instance should be configured for each targeted platform. - -## βš™οΈ Inputs - -| Name | Description | Required | Default | -| ----------------- | ---------------------------------------------------------------------------------- | -------- | ----------------- | -| `artifact-name` | Name of an artifact to download into the build context before building, e.g. a jar produced by an earlier job (leave empty to skip) | No | `""` | -| `artifact-path` | Destination path for the downloaded artifact, relative to the workspace (ignored if `artifact-name` is empty) | No | `""` | -| `attest` | Generate & sign a keyless SLSA build provenance attestation for the pushed image (requires `push: true` and caller permissions, see notes) | No | `false` | -| `build-args` | Docker build arguments (multiline format: `KEY1=value1\nKEY2=value2`) | No | `""` | -| `context` | Path to Docker Build Context | No | `"."` | -| `dockerfile` | Path to the Dockerfile to build (e.g., './Dockerfile', './docker/Dockerfile') | No | `"Dockerfile"` | -| `hadolint` | Enable Hadolint | No | `true` | -| `image-name` | Name of Docker Image (e.g., 'myimage', 'myorg/myimage') | true | - | -| `image-tag` | Tag to apply to the built image (e.g., 'latest', 'v1.2.3') | No | `"latest"` | -| `platform` | Indicates which platform the image should be built for | No | `"linux/amd64"` | -| `push` | Push Docker Image to Registry | No | `false` | -| `registry` | Docker Registry | No | `"docker.io"` | -| `runner` | GitHub Actions runner label | No | `"ubuntu-latest"` | -| `security-report` | Security Report Mode (`"sarif"` \| `"comment"`; ignored if `security-scan: false`) | No | `"sarif"` | -| `security-scan` | Enable Trivy Security Scan | No | `true` | -| `trivy-version` | Override Trivy security scanner version | No | `v0.71.0` | +> [!IMPORTANT] Due to a limitation on Trivy analysis, the workflow targets a single platform. A workflow instance should be configured for each targeted platform. + +## βš™οΈ Inputs + +| Name | Description | Required | Default | +| --- | --- | --- | --- | +| `artifact-name` | Name of an artifact to download into the build context before building, e.g. a jar produced by an earlier job (leave empty to skip) | No | `""` | +| `artifact-path` | Destination path for the downloaded artifact, relative to the workspace (ignored if `artifact-name` is empty) | No | `""` | +| `attest` | Generate & sign a keyless SLSA build provenance attestation for the pushed image (requires `push: true` and caller permissions, see notes) | No | `false` | +| `build-args` | Docker build arguments (multiline format: `KEY1=value1\nKEY2=value2`) | No | `""` | +| `context` | Path to Docker Build Context | No | `"."` | +| `dockerfile` | Path to the Dockerfile to build (e.g., './Dockerfile', './docker/Dockerfile') | No | `"Dockerfile"` | +| `hadolint` | Enable Hadolint | No | `true` | +| `image-name` | Name of Docker Image (e.g., 'myimage', 'myorg/myimage') | true | - | +| `image-tag` | Tag to apply to the built image (e.g., 'latest', 'v1.2.3') | No | `"latest"` | +| `platform` | Indicates which platform the image should be built for | No | `"linux/amd64"` | +| `push` | Push Docker Image to Registry | No | `false` | +| `registry` | Docker Registry | No | `"docker.io"` | +| `runner` | GitHub Actions runner label | No | `"ubuntu-latest"` | +| `security-report` | Security Report Mode (`"sarif"` \| `"comment"`; ignored if `security-scan: false`) | No | `"sarif"` | +| `security-scan` | Enable Trivy Security Scan | No | `true` | +| `trivy-version` | Override Trivy security scanner version | No | `v0.71.0` | ## πŸ” Secrets -| Name | Description | Required | -| -------------------- | --------------------------------------------------------------------------------------------------- | ------------------ | -| `dockerhub-username` | Username for Docker Hub authentication | Yes | -| `dockerhub-password` | Token for Docker Hub authentication (with read-only permissions) | Yes | -| `username` | Username for Docker Registry authentication | When `push: true` | -| `password` | Password or Personal Access Token for Docker registry authentication (with appropriate permissions) | When `push: true` | +| Name | Description | Required | +| --- | --- | --- | +| `dockerhub-username` | Username for Docker Hub authentication | Yes | +| `dockerhub-password` | Token for Docker Hub authentication (with read-only permissions) | Yes | +| `username` | Username for Docker Registry authentication | When `push: true` | +| `password` | Password or Personal Access Token for Docker registry authentication (with appropriate permissions) | When `push: true` | ## πŸ“€ Outputs -| Name | Description | -| --- | --- | +| Name | Description | +| ---------- | -------------------------------------- | | `checksum` | Checksum (`0x...`) of the Docker image | The built image tag, digest and checksum are visible on the workflow run summary. diff --git a/docker-build/workflow-sha256 b/docker-build/workflow-sha256 index 56ab73f..80147d5 100644 --- a/docker-build/workflow-sha256 +++ b/docker-build/workflow-sha256 @@ -1 +1 @@ -c1688238c51571ebf2755cee205def80d47878ca649d17f2f216b4d979d534fe +25895c20dacd914da70625a96d8be611b257dffdce92c349a561461988d1e29f diff --git a/docker-promote/README.md b/docker-promote/README.md index 986cbf3..99b68e9 100644 --- a/docker-promote/README.md +++ b/docker-promote/README.md @@ -6,8 +6,7 @@ This reusable GitHub Actions workflow promotes an image that was already built, The calling workflow must trigger promotion from a release tag such as `vX.Y.Z`, or `component-vX.Y.Z` when release-please includes the component name in the tag. -> [!IMPORTANT] -> Promotion never rebuilds the image. CI must have built and pushed the source tag for the tagged commit before this workflow can promote it. +> [!IMPORTANT] Promotion never rebuilds the image. CI must have built and pushed the source tag for the tagged commit before this workflow can promote it. ## Features @@ -31,10 +30,10 @@ The calling workflow must trigger promotion from a release tag such as `vX.Y.Z`, ## Secrets -| Name | Description | Required | -| --- | --- | --- | -| `username` | Registry username | Yes | -| `password` | Registry password with read and write access | Yes | +| Name | Description | Required | +| ---------- | -------------------------------------------- | -------- | +| `username` | Registry username | Yes | +| `password` | Registry password with read and write access | Yes | ## Example Usage diff --git a/docker-promote/workflow-sha256 b/docker-promote/workflow-sha256 index cc1689e..3c47217 100644 --- a/docker-promote/workflow-sha256 +++ b/docker-promote/workflow-sha256 @@ -1 +1 @@ -d484d87dfb116f8f46519733d75e444f3f417f83eb19b21423420bf5ec9a2c8c +bae0d1c5a9f086031b7e33d60555788f3827e68ff87cbb68ba89b9c2f5e9482c diff --git a/java-build/README.md b/java-build/README.md index 4693581..d8866dd 100644 --- a/java-build/README.md +++ b/java-build/README.md @@ -2,12 +2,9 @@ ## πŸ” Overview -This reusable GitHub Actions workflow builds, tests and analyses a Gradle-based Java project. -It is the GitHub Actions counterpart of the `buildJavaProject` Jenkins pipeline used by the iExec middleware -services, and covers the path from a checkout to a jar handed over to an OCI image build. +This reusable GitHub Actions workflow builds, tests and analyses a Gradle-based Java project. It is the GitHub Actions counterpart of the `buildJavaProject` Jenkins pipeline used by the iExec middleware services, and covers the path from a checkout to a jar handed over to an OCI image build. -It serves both services and pure libraries, so anything only a service needs β€” the Docker Hub login for -Testcontainers, the jar upload β€” is opt-in and left to the caller. +It serves both services and pure libraries, so anything only a service needs β€” the Docker Hub login for Testcontainers, the jar upload β€” is opt-in and left to the caller. ## ✨ Features @@ -20,36 +17,35 @@ Testcontainers, the jar upload β€” is opt-in and left to the caller. ## βš™οΈ Inputs -| Name | Description | Required | Default | -| ------------------------- | ------------------------------------------------------------------------------------------------ | -------- | ----------------- | -| `artifact-name` | Name of the uploaded jar artifact | No | `"boot-jar"` | -| `artifact-retention-days` | Retention of the uploaded jar artifact, in days | No | `1` | -| `dockerhub-login` | Log in to Docker Hub before the build. Enable it when the tests pull images, e.g. Testcontainers | No | `false` | -| `java-version` | Java version to use | No | `"21"` | -| `refresh-dependencies` | Run Gradle with `--refresh-dependencies` (only useful for `-SNAPSHOT` or dynamic versions) | No | `false` | -| `run-itest` | Run the `itest` Gradle task after the unit tests | No | `false` | -| `sonar` | Run the SonarQube/SonarCloud analysis | No | `false` | -| `upload-jar` | Upload the built jar as an artifact, so that a later job can build an OCI image from it | No | `false` | +| Name | Description | Required | Default | +| --- | --- | --- | --- | +| `artifact-name` | Name of the uploaded jar artifact | No | `"boot-jar"` | +| `artifact-retention-days` | Retention of the uploaded jar artifact, in days | No | `1` | +| `dockerhub-login` | Log in to Docker Hub before the build. Enable it when the tests pull images, e.g. Testcontainers | No | `false` | +| `java-version` | Java version to use | No | `"21"` | +| `refresh-dependencies` | Run Gradle with `--refresh-dependencies` (only useful for `-SNAPSHOT` or dynamic versions) | No | `false` | +| `run-itest` | Run the `itest` Gradle task after the unit tests | No | `false` | +| `sonar` | Run the SonarQube/SonarCloud analysis | No | `false` | +| `upload-jar` | Upload the built jar as an artifact, so that a later job can build an OCI image from it | No | `false` | ## πŸ” Secrets -| Name | Description | Required | -| -------------------- | -------------------------------- | ---------------------------- | -| `dockerhub-username` | Docker Hub username | When `dockerhub-login: true` | -| `dockerhub-password` | Docker Hub token | When `dockerhub-login: true` | -| `sonar-token` | SonarCloud token | When `sonar: true` | +| Name | Description | Required | +| -------------------- | ------------------- | ---------------------------- | +| `dockerhub-username` | Docker Hub username | When `dockerhub-login: true` | +| `dockerhub-password` | Docker Hub token | When `dockerhub-login: true` | +| `sonar-token` | SonarCloud token | When `sonar: true` | ## πŸ“€ Outputs -| Name | Description | -| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `jar-path` | Path of the Gradle project built jar. Feed it to `docker-build.yml` as `build-args: jar=`. Only set when `upload-jar: true`, empty for pure libraries | -| `artifact-name` | Name of the uploaded jar artifact, echoed back for convenience | +| Name | Description | +| --- | --- | +| `jar-path` | Path of the Gradle project built jar. Feed it to `docker-build.yml` as `build-args: jar=`. Only set when `upload-jar: true`, empty for pure libraries | +| `artifact-name` | Name of the uploaded jar artifact, echoed back for convenience | ## πŸ’» Example Usage -Building and testing a service, then building an OCI image from the very same jar. `upload-jar` is opt-in -because the workflow also serves pure libraries, which have no image to build and nothing to hand over: +Building and testing a service, then building an OCI image from the very same jar. `upload-jar` is opt-in because the workflow also serves pure libraries, which have no image to build and nothing to hand over: ```yaml name: CI @@ -96,38 +92,17 @@ jobs: ## πŸ“ Notes -- πŸ”Ž The SonarQube Gradle plugin reads the branch, pull request number and repository from the `GITHUB_*` environment - variables, so none of the `sonar.pullrequest.*` or `sonar.branch.name` properties need to be passed. - The `sonar.projectKey` property is derived from SonarQube Gradle plugin and Gradle project properties. - The `sonar.organization` property (mandatory on SonarQube Cloud) is not auto-detected and derived from the calling repository. - The checkout uses `fetch-depth: 0` because Sonar attributes lines to authors through `git blame`. -- 🏷️ The checkout also needs the full history because the iExec `build.gradle` files derive the project version - from the tag pointing at `HEAD`, appending `-NEXT-SNAPSHOT` when there is none. -- πŸ”„ `refresh-dependencies` defaults to `false`. `setup-gradle` caches the Gradle home between runs β€” writing it - from the default branch and restoring it read-only elsewhere β€” so a build can legitimately resolve against a - cache populated days earlier. That only matters for changing modules (`-SNAPSHOT`) and dynamic versions, which - Gradle re-checks at most every 24 hours; enable the input when a project depends on one. For the pinned versions - the iExec projects resolve from jitpack, it forces Gradle to revalidate the metadata of every module on every - build for no benefit. -- πŸ“€ The jar artifact is uploaded flat, so `artifact-path: build/libs` in `docker-build.yml` restores it at the - path reported by the `jar-path` output. -- 🧩 Pure libraries pass `upload-jar: false`: no artifact is uploaded and the `jar-path` output is never set - (it evaluates to an empty string on the caller side, which is safe to ignore). -- πŸ” The workflow declares `permissions: contents: read` + `actions: write`: the first is needed by `checkout`, - the second by `upload-artifact`. An explicit `permissions` block resets every other scope to `none`, so dropping - `actions: write` silently breaks the report artifact. -- 🌐 The `test-reports` artifact (7-day retention) contains the human-readable HTML reports from `build/reports` - (unit tests, JaCoCo coverage). GitHub does not render HTML inline on a PR: open it from PR β†’ **Checks** β†’ the run - β†’ **Summary** (bottom *Artifacts* section), download, unzip and open locally. `upload-artifact` also exposes an - `artifact-url` output if you later want to post a direct download link as a PR comment. +- πŸ”Ž The SonarQube Gradle plugin reads the branch, pull request number and repository from the `GITHUB_*` environment variables, so none of the `sonar.pullrequest.*` or `sonar.branch.name` properties need to be passed. The `sonar.projectKey` property is derived from SonarQube Gradle plugin and Gradle project properties. The `sonar.organization` property (mandatory on SonarQube Cloud) is not auto-detected and derived from the calling repository. The checkout uses `fetch-depth: 0` because Sonar attributes lines to authors through `git blame`. +- 🏷️ The checkout also needs the full history because the iExec `build.gradle` files derive the project version from the tag pointing at `HEAD`, appending `-NEXT-SNAPSHOT` when there is none. +- πŸ”„ `refresh-dependencies` defaults to `false`. `setup-gradle` caches the Gradle home between runs β€” writing it from the default branch and restoring it read-only elsewhere β€” so a build can legitimately resolve against a cache populated days earlier. That only matters for changing modules (`-SNAPSHOT`) and dynamic versions, which Gradle re-checks at most every 24 hours; enable the input when a project depends on one. For the pinned versions the iExec projects resolve from jitpack, it forces Gradle to revalidate the metadata of every module on every build for no benefit. +- πŸ“€ The jar artifact is uploaded flat, so `artifact-path: build/libs` in `docker-build.yml` restores it at the path reported by the `jar-path` output. +- 🧩 Pure libraries pass `upload-jar: false`: no artifact is uploaded and the `jar-path` output is never set (it evaluates to an empty string on the caller side, which is safe to ignore). +- πŸ” The workflow declares `permissions: contents: read` + `actions: write`: the first is needed by `checkout`, the second by `upload-artifact`. An explicit `permissions` block resets every other scope to `none`, so dropping `actions: write` silently breaks the report artifact. +- 🌐 The `test-reports` artifact (7-day retention) contains the human-readable HTML reports from `build/reports` (unit tests, JaCoCo coverage). GitHub does not render HTML inline on a PR: open it from PR β†’ **Checks** β†’ the run β†’ **Summary** (bottom _Artifacts_ section), download, unzip and open locally. `upload-artifact` also exposes an `artifact-url` output if you later want to post a direct download link as a PR comment. ## πŸ› οΈ Troubleshooting -- **`Could not resolve com.github.iExecBlockchainComputing...`** β€” the dependency is not on jitpack yet. jitpack - builds a version on first request, so a freshly pushed tag can take a few minutes to become resolvable. -- **`Cannot perform inline analysis, no branch or pull request found`** β€” the checkout is shallow. This workflow - sets `fetch-depth: 0`; a caller wrapping it differently has to do the same. -- **`You must define the following mandatory properties ... sonar.organization`** β€” the SonarQube Cloud organization - could not be resolved. Either the repository owner is not a SonarQube Cloud organization key, or the project - lives under a different one. Update the project configuration on SonarQube Cloud. +- **`Could not resolve com.github.iExecBlockchainComputing...`** β€” the dependency is not on jitpack yet. jitpack builds a version on first request, so a freshly pushed tag can take a few minutes to become resolvable. +- **`Cannot perform inline analysis, no branch or pull request found`** β€” the checkout is shallow. This workflow sets `fetch-depth: 0`; a caller wrapping it differently has to do the same. +- **`You must define the following mandatory properties ... sonar.organization`** β€” the SonarQube Cloud organization could not be resolved. Either the repository owner is not a SonarQube Cloud organization key, or the project lives under a different one. Update the project configuration on SonarQube Cloud. - **Testcontainers fails pulling an image** β€” set `dockerhub-login: true` and pass the Docker Hub secrets. diff --git a/propose-safe-multisig-tx/README.md b/propose-safe-multisig-tx/README.md index d4b6069..620b9ac 100644 --- a/propose-safe-multisig-tx/README.md +++ b/propose-safe-multisig-tx/README.md @@ -6,22 +6,22 @@ This reusable GitHub Actions workflow automates the process of proposing transac ## Workflow Inputs πŸ› οΈ -| **Input** | **Description** | **Required** | **Default** | -| ------------------------ | ------------------------------------------------------------- | ------------ | ----------------------------------- | -| **safe-address** | Address of the Safe contract | Yes | - | -| **transaction-to** | Target address for the transaction | Yes | - | -| **transaction-value** | Value to send in the transaction (in wei) | No | `0` | -| **transaction-data** | Transaction data/calldata | Yes | - | -| **rpc-url** | RPC URL for the blockchain network | Yes (Secret) | - | -| **safe-proposer-private-key** | Private key of the proposer wallet | Yes (Secret) | - | -| **safe-api-key** | Safe API key for transaction service | Yes (Secret) | - | +| **Input** | **Description** | **Required** | **Default** | +| --- | --- | --- | --- | +| **safe-address** | Address of the Safe contract | Yes | - | +| **transaction-to** | Target address for the transaction | Yes | - | +| **transaction-value** | Value to send in the transaction (in wei) | No | `0` | +| **transaction-data** | Transaction data/calldata | Yes | - | +| **rpc-url** | RPC URL for the blockchain network | Yes (Secret) | - | +| **safe-proposer-private-key** | Private key of the proposer wallet | Yes (Secret) | - | +| **safe-api-key** | Safe API key for transaction service | Yes (Secret) | - | ## Workflow Outputs πŸ“€ -| **Output** | **Description** | -| ----------------- | ----------------------------------------- | -| **tx-hash** | Hash of the Safe transaction created | -| **tx-details** | Complete transaction details (JSON) | +| **Output** | **Description** | +| -------------- | ------------------------------------ | +| **tx-hash** | Hash of the Safe transaction created | +| **tx-details** | Complete transaction details (JSON) | ## How to Use This Reusable Workflow πŸ”„ @@ -29,23 +29,23 @@ This reusable GitHub Actions workflow automates the process of proposing transac In another workflow file, invoke this reusable workflow like so: ```yaml - name: Upgrade contract - - on: - workflow_dispatch: - - jobs: - upgrade: - uses: ./.github/workflows/propose-safe-multisig-tx.yml - secrets: - rpc-url: ${{ secrets.RPC_URL }} - safe-proposer-private-key: ${{ secrets.SAFE_PROPOSER_PRIVATE_KEY }} - safe-api-key: ${{ secrets.SAFE_API_KEY }} - with: - safe-address: '0xab...' - transaction-to: '0xcd...' - transaction-value: '0' - transaction-data: '0xef' # Upgrade transaction calldata + name: Upgrade contract + + on: + workflow_dispatch: + + jobs: + upgrade: + uses: ./.github/workflows/propose-safe-multisig-tx.yml + secrets: + rpc-url: ${{ secrets.RPC_URL }} + safe-proposer-private-key: ${{ secrets.SAFE_PROPOSER_PRIVATE_KEY }} + safe-api-key: ${{ secrets.SAFE_API_KEY }} + with: + safe-address: "0xab..." + transaction-to: "0xcd..." + transaction-value: "0" + transaction-data: "0xef" # Upgrade transaction calldata ``` 2. **Configure Secrets** diff --git a/propose-safe-multisig-tx/src/env.ts b/propose-safe-multisig-tx/src/env.ts index 41a6cbc..82b128a 100644 --- a/propose-safe-multisig-tx/src/env.ts +++ b/propose-safe-multisig-tx/src/env.ts @@ -1,5 +1,5 @@ -import 'dotenv/config'; -import { z } from 'zod'; +import "dotenv/config"; +import { z } from "zod"; const addressRegex = /(^|\b)(0x)?[0-9a-fA-F]{40}(\b|$)/; const privateKeyRegex = /(^|\b)(0x)?[0-9a-fA-F]{64}(\b|$)/; diff --git a/propose-safe-multisig-tx/src/index.ts b/propose-safe-multisig-tx/src/index.ts index e450ab1..b7871d9 100644 --- a/propose-safe-multisig-tx/src/index.ts +++ b/propose-safe-multisig-tx/src/index.ts @@ -1,4 +1,4 @@ -import * as core from '@actions/core'; +import * as core from "@actions/core"; import SafeApiKit from "@safe-global/api-kit"; import Safe from "@safe-global/protocol-kit"; import { OperationType, MetaTransactionData } from "@safe-global/types-kit"; @@ -18,7 +18,9 @@ async function run() { DRY_RUN: dryRun, } = env; - core.info(`πŸš€ Starting Safe transaction ${dryRun ? 'validation (DRY RUN)' : 'proposal'}...`); + core.info( + `πŸš€ Starting Safe transaction ${dryRun ? "validation (DRY RUN)" : "proposal"}...`, + ); core.info(`πŸ“ Safe Address: ${safeAddress}`); core.info(`🎯 Target Address: ${transactionTo}`); @@ -68,17 +70,20 @@ async function run() { core.info(` Value: ${safeTransactionData.value}`); core.info(` Data: ${safeTransactionData.data}`); core.info(` Operation: ${safeTransactionData.operation}`); - + core.setOutput("tx-hash", safeTxHash); - core.setOutput("tx-details", JSON.stringify({ - to: safeTransactionData.to, - value: safeTransactionData.value, - data: safeTransactionData.data, - operation: safeTransactionData.operation, - safeTxHash: safeTxHash, - senderAddress: account.address, - dryRun: true, - })); + core.setOutput( + "tx-details", + JSON.stringify({ + to: safeTransactionData.to, + value: safeTransactionData.value, + data: safeTransactionData.data, + operation: safeTransactionData.operation, + safeTxHash: safeTxHash, + senderAddress: account.address, + dryRun: true, + }), + ); core.info(`βœ… Transaction validated successfully (not proposed)`); core.info(`πŸ”— Transaction Hash (would be): ${safeTxHash}`); @@ -100,7 +105,9 @@ async function run() { core.info(`βœ… Transaction proposed successfully!`); core.info(`πŸ”— Transaction Hash: ${safeTxHash}`); core.info(`⏳ Waiting for other owners to sign and execute...`); - core.info(`πŸ“‹ Transaction Details: ${JSON.stringify(transaction, null, 2)}`); + core.info( + `πŸ“‹ Transaction Details: ${JSON.stringify(transaction, null, 2)}`, + ); } } diff --git a/propose-safe-multisig-tx/workflow-sha256 b/propose-safe-multisig-tx/workflow-sha256 index b67026b..fd8c078 100644 --- a/propose-safe-multisig-tx/workflow-sha256 +++ b/propose-safe-multisig-tx/workflow-sha256 @@ -1 +1 @@ -20270bfd49e14744aac321cd791e23f25aff4e36df2176bb9fb3eb52047cc624 +fd5f2c5b52e9fba44a86fe2b8f0b5e38fe04bf464ca4ac8a65f3d850f53a9426 diff --git a/publish-npm/README.md b/publish-npm/README.md index 8adb335..8f4b12f 100644 --- a/publish-npm/README.md +++ b/publish-npm/README.md @@ -2,8 +2,7 @@ ## Overview 🌟 -This reusable GitHub Actions workflow automates the process of publishing an NPM package. It is configurable via inputs -for the package scope, Node.js version, registry URL, and other options. The workflow performs the following actions: +This reusable GitHub Actions workflow automates the process of publishing an NPM package. It is configurable via inputs for the package scope, Node.js version, registry URL, and other options. The workflow performs the following actions: - **Downloads Artifacts**: Downloads specified artifacts if needed. πŸ“¦ - **Checks Out Your Repository**: Retrieves your code. πŸ“₯ @@ -15,38 +14,37 @@ for the package scope, Node.js version, registry URL, and other options. The wor - **Checks Code Formatting**: Verifies code formatting if configured. 🧹 - **Runs Linting**: Performs code linting if configured. 🧹 - **Runs Tests**: Executes unit tests if enabled. βœ… -- **Publishes the Package**: Publishes the package with provenance (if enabled) and the specified access level using - `npm publish`. πŸŽ‰ +- **Publishes the Package**: Publishes the package with provenance (if enabled) and the specified access level using `npm publish`. πŸŽ‰ ## Workflow Inputs πŸ› οΈ -| **Input** | **Description** | **Required** | **Default** | -| ------------------------ | ------------------------------------------------------------- | ------------ | ----------------------------------- | -| **scope** | NPM package scope (e.g., `@iexec`). | No | `@iexec` | -| **node-version** | Node.js version to use. | No | `20` | -| **registry** | NPM registry URL. | No | `https://registry.npmjs.org` | -| **access** | Package access (public or restricted). | No | `public` | -| **provenance** | Enable npm provenance. | No | `true` | -| **install-command** | Install dependencies command. | No | `npm ci` | -| **build-command** | Build package command. | No | `npm run build` | -| **run-tests** | Execute unit tests step. | No | `false` | -| **test-command** | Run unit tests command. | No | `npm test --if-present` | -| **lint-command** | Run linting command. | No | `npm run lint --if-present` | -| **type-check-command** | Run type-checking command. | No | `npm run check-types --if-present` | -| **format-check-command** | Run format-checking command. | No | `npm run check-format --if-present` | -| **environment** | GitHub environment. | No | `production` | -| **tag** | npm publish tag (e.g., latest, nightly). | No | `''` (empty string) | -| **working-directory** | Directory containing package.json. | No | `''` (empty string) | -| **artifact-name** | Name of an artifact to download before the build. | No | `''` (empty string) | -| **artifact-path** | Destination path for the downloaded artifact. | No | `''` (empty string) | -| **version** | Version to publish (leave empty to use package.json version). | No | `''` (empty string) | -| **dry-run** | Run in dry-run mode (the package will not be published). | No | `false` | +| **Input** | **Description** | **Required** | **Default** | +| --- | --- | --- | --- | +| **scope** | NPM package scope (e.g., `@iexec`). | No | `@iexec` | +| **node-version** | Node.js version to use. | No | `20` | +| **registry** | NPM registry URL. | No | `https://registry.npmjs.org` | +| **access** | Package access (public or restricted). | No | `public` | +| **provenance** | Enable npm provenance. | No | `true` | +| **install-command** | Install dependencies command. | No | `npm ci` | +| **build-command** | Build package command. | No | `npm run build` | +| **run-tests** | Execute unit tests step. | No | `false` | +| **test-command** | Run unit tests command. | No | `npm test --if-present` | +| **lint-command** | Run linting command. | No | `npm run lint --if-present` | +| **type-check-command** | Run type-checking command. | No | `npm run check-types --if-present` | +| **format-check-command** | Run format-checking command. | No | `npm run check-format --if-present` | +| **environment** | GitHub environment. | No | `production` | +| **tag** | npm publish tag (e.g., latest, nightly). | No | `''` (empty string) | +| **working-directory** | Directory containing package.json. | No | `''` (empty string) | +| **artifact-name** | Name of an artifact to download before the build. | No | `''` (empty string) | +| **artifact-path** | Destination path for the downloaded artifact. | No | `''` (empty string) | +| **version** | Version to publish (leave empty to use package.json version). | No | `''` (empty string) | +| **dry-run** | Run in dry-run mode (the package will not be published). | No | `false` | ### Secrets πŸ” -| **Secret** | **Description** | **Required** | -| ------------- | ---------------------------------------------------------------------------------------------- | ------------ | -| **npm-token** | NPM auth token (required unless `dry-run: true` or workflow is called by a trusted publisher). | No | +| **Secret** | **Description** | **Required** | +| --- | --- | --- | +| **npm-token** | NPM auth token (required unless `dry-run: true` or workflow is called by a trusted publisher). | No | ## Job and Steps βš™οΈ @@ -98,8 +96,7 @@ for the package scope, Node.js version, registry URL, and other options. The wor 2. **Configure Trusted Publisher on NPM** - On [npmjs.com](https://www.npmjs.com/), configure the root publish workflow of your GitHub repository as a trusted publisher for your package. - ![trusted publisher](trusted-publisher.png) + On [npmjs.com](https://www.npmjs.com/), configure the root publish workflow of your GitHub repository as a trusted publisher for your package. ![trusted publisher](trusted-publisher.png) NB: You can have only one trusted publisher per package, if you need multiple publication triggers (workflow_dispatch, release, etc.), you need to merge them into a single workflow referenced as trusted publisher. @@ -135,8 +132,7 @@ for the package scope, Node.js version, registry URL, and other options. The wor 2. **Configure Secrets** - Ensure that the `NPM_TOKEN` secret is added to your repository’s settings. This token is required to authenticate - with the NPM registry during publishing. πŸ”‘ + Ensure that the `NPM_TOKEN` secret is added to your repository’s settings. This token is required to authenticate with the NPM registry during publishing. πŸ”‘ ## Workflow Steps in Detail πŸ” diff --git a/release-please/README.md b/release-please/README.md index f982fc5..493ea8c 100644 --- a/release-please/README.md +++ b/release-please/README.md @@ -42,13 +42,13 @@ This file, placed at the root of your project, defines the schema, customizes th This file tracks the published versions by **release-please**. You can start with it empty if your project has no version yet, or pre-fill it with versions if necessary. -*Empty initialization:* +_Empty initialization:_ ```json {} ``` -*Or with predefined versions:* +_Or with predefined versions:_ ```json { @@ -161,4 +161,4 @@ For a monorepo containing several projects, the configuration allows you to mana - **Workflow:** The YAML workflow file remains the same, triggering the release process for all defined packages according to the configuration. -This documentation helps you automate and centralize your release process effectively, leveraging the flexibility provided by **release-please**. Feel free to adapt these examples to your specific requirements and consult the [official documentation](https://github.com/googleapis/release-please) for more options and details! \ No newline at end of file +This documentation helps you automate and centralize your release process effectively, leveraging the flexibility provided by **release-please**. Feel free to adapt these examples to your specific requirements and consult the [official documentation](https://github.com/googleapis/release-please) for more options and details! diff --git a/rust-build/README.md b/rust-build/README.md index d22b56f..104d5ae 100644 --- a/rust-build/README.md +++ b/rust-build/README.md @@ -25,8 +25,8 @@ jobs: build-and-test: uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/rust-build.yml@main with: - rust-version: 'stable' - working-directory: './my-crate' + rust-version: "stable" + working-directory: "./my-crate" enable-cache: true publish-crates-io: false secrets: @@ -35,19 +35,19 @@ jobs: ## Inputs -| Name | Description | Default | Required | -| ------------------- | --------------------------------------------------------- | -------- | -------- | -| `rust-version` | Rust version to use | `stable` | No | -| `working-directory` | The directory to run jobs from | `.` | No | -| `enable-cache` | Enable caching of dependencies | `true` | No | -| `publish-crates-io` | Publish the package to crates.io (only if build succeeds) | `false` | No | +| Name | Description | Default | Required | +| --- | --- | --- | --- | +| `rust-version` | Rust version to use | `stable` | No | +| `working-directory` | The directory to run jobs from | `.` | No | +| `enable-cache` | Enable caching of dependencies | `true` | No | +| `publish-crates-io` | Publish the package to crates.io (only if build succeeds) | `false` | No | Note: All builds use the release profile by default. There is no build-target input anymore ## Secrets -| Name | Description | Required | -| ---------------------- | --------------------------------------- | ------------------------------------- | +| Name | Description | Required | +| --- | --- | --- | | `CARGO_REGISTRY_TOKEN` | crates.io API token for `cargo publish` | Only if `publish-crates-io` is `true` | ## Examples @@ -67,7 +67,7 @@ jobs: build-and-test: uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/rust-build.yml@main with: - working-directory: './my-crate' + working-directory: "./my-crate" ``` ### Publish to crates.io (requires CARGO_REGISTRY_TOKEN) @@ -80,4 +80,4 @@ jobs: publish-crates-io: true secrets: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} -``` \ No newline at end of file +``` diff --git a/rust-build/workflow-sha256 b/rust-build/workflow-sha256 index 1beb714..0ae4a92 100644 --- a/rust-build/workflow-sha256 +++ b/rust-build/workflow-sha256 @@ -1 +1 @@ -cc034c9a999a64610979272458e185e098b3a288bbe41cd267a577bff679135a +64dfabf72bbdfb5babe8ace19240ef5f799531950a4de7962f615837fe2176a5 From 99a3d16c22f6be25c889565ad2cffe4e7bc4c5fe Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Mon, 5 Oct 2026 10:07:09 +0200 Subject: [PATCH 3/4] docs: emphasis update-checksums after format --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4cbd95e..4cb73b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,7 +22,7 @@ Files are formatted with [Prettier](https://prettier.io), using its default sett mise run format ``` -Formatting can rewrite workflow files, which changes their checksum. After editing a workflow, run `mise run update-checksums` instead of `mise run format` alone, so `workflow-sha256` files are computed from the formatted content. +> [!IMPORTANT] Formatting can rewrite workflow files, which changes their checksum. After editing a workflow, run `mise run update-checksums` instead of `mise run format` alone, so `workflow-sha256` files are computed from the formatted content. ## Linting From 284341c432d5f685e490bf473b79d3b487345e97 Mon Sep 17 00:00:00 2001 From: Pierre Jeanjacquot <26487010+PierreJeanjacquot@users.noreply.github.com> Date: Mon, 5 Oct 2026 10:38:07 +0200 Subject: [PATCH 4/4] refactor: trigger all verifications from a single "verify-all" task --- .../validate-release-please-config.yml | 33 ----------------- .../workflows/{lint.yml => verify-all.yml} | 10 ++--- .github/workflows/verify-workflow-sha256.yml | 36 ------------------ CONTRIBUTING.md | 37 ++++++++++++++----- mise.toml | 18 +++++++++ 5 files changed, 51 insertions(+), 83 deletions(-) delete mode 100644 .github/workflows/validate-release-please-config.yml rename .github/workflows/{lint.yml => verify-all.yml} (79%) delete mode 100644 .github/workflows/verify-workflow-sha256.yml diff --git a/.github/workflows/validate-release-please-config.yml b/.github/workflows/validate-release-please-config.yml deleted file mode 100644 index fdf1cf3..0000000 --- a/.github/workflows/validate-release-please-config.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Validate release-please config - -on: - pull_request: - branches: - - main - paths: - - "release-please-config.json" - - "scripts/check-release-please-config.sh" - - ".github/workflows/validate-release-please-config.yml" - push: - branches: - - main - paths: - - "release-please-config.json" - - "scripts/check-release-please-config.sh" - - ".github/workflows/validate-release-please-config.yml" - -permissions: - contents: read - -concurrency: - group: validate-release-please-config-${{ github.ref }} - cancel-in-progress: true - -jobs: - validate: - name: Validate release-please-config.json - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - name: Run config validation - run: bash scripts/check-release-please-config.sh release-please-config.json diff --git a/.github/workflows/lint.yml b/.github/workflows/verify-all.yml similarity index 79% rename from .github/workflows/lint.yml rename to .github/workflows/verify-all.yml index d306f40..bc8bb6f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/verify-all.yml @@ -1,4 +1,4 @@ -name: Lint +name: Verify all on: push: @@ -7,14 +7,14 @@ on: permissions: {} -# Cancelling a push to main would leave that commit unlinted. +# Cancelling a push to main would leave that commit unverified. concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: lint: - name: Lint + name: Verify all runs-on: ubuntu-latest permissions: contents: read # required for checkout @@ -27,5 +27,5 @@ jobs: uses: jdx/mise-action@c2a87611a18de5b3828c5652fe268e992400cb5c # v4.3.0 with: minimum_release_age: 7d - - name: Run lint - run: mise run lint + - name: Run verify-all + run: mise run verify-all diff --git a/.github/workflows/verify-workflow-sha256.yml b/.github/workflows/verify-workflow-sha256.yml deleted file mode 100644 index a2d3ae6..0000000 --- a/.github/workflows/verify-workflow-sha256.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: verify-workflow-sha256 - -on: - pull_request: - branches: - - main - paths: - - ".github/workflows/*.yml" - - "release-please-config.json" - - "scripts/compute-workflow-sha256.sh" - - "**/workflow-sha256" - push: - branches: - - main - paths: - - ".github/workflows/*.yml" - - "release-please-config.json" - - "scripts/compute-workflow-sha256.sh" - - "**/workflow-sha256" - -permissions: - contents: read - -concurrency: - group: verify-workflow-sha256-${{ github.ref }} - cancel-in-progress: true - -jobs: - verify-workflow-sha256: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - name: Verify workflow-sha256 files are up to date - run: bash scripts/compute-workflow-sha256.sh --check diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4cb73b4..4af97d9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,30 @@ # Contributing +## Verifying your changes + +All dev tools are pinned in `mise.toml` and `mise.lock`. Install them with [mise](https://mise.jdx.dev): + +```sh +mise install --locked +``` + +Then, before pushing, run: + +```sh +mise run verify-all +``` + +CI runs the same command on every pull request and on every push to `main`. It runs these tasks: + +- `lint`: runs all linters (see [Linting](#linting)) + - `lint:format`: checks formatting with Prettier + - `lint:actionlint`: lints GitHub Actions workflows with actionlint + - `lint:shellcheck`: lints shell scripts with shellcheck +- `check-checksums`: checks that `workflow-sha256` files match their workflows (see [Editing a reusable workflow](#editing-a-reusable-workflow)) +- `check-release-please-config`: validates `release-please-config.json`, checking that every package declares a component and that keys are ordered + +You can run any of these on its own, e.g. `mise run lint:shellcheck`. Run `mise tasks` to list all tasks. + ## Editing a reusable workflow Each shared reusable workflow is backed by a Component directory `/` that release-please versions independently. Release-please only sees changes under `/`, so a commit that only edits the workflow file is otherwise invisible to it. @@ -12,7 +37,7 @@ mise run update-checksums This formats the repository (see [Formatting](#formatting)), then runs `scripts/compute-workflow-sha256.sh`, which regenerates `/workflow-sha256`, a checksum of the workflow file. Commit the resulting diff alongside your workflow change β€” this is what makes the change visible to release-please for that Component. -CI enforces this on every pull request via `bash scripts/compute-workflow-sha256.sh --check`, which fails if any `workflow-sha256` file is out of date. +`mise run verify-all` enforces this through the `check-checksums` task, which fails if any `workflow-sha256` file is out of date. ## Formatting @@ -26,19 +51,13 @@ mise run format ## Linting -Workflows are linted with [actionlint](https://github.com/rhysd/actionlint), which also runs [shellcheck](https://github.com/koalaman/shellcheck) on inline `run:` scripts. Shell scripts committed to the repository (`*.sh`, e.g. under `scripts/`) are linted with shellcheck directly. Formatting is checked with `prettier --check`. All tools are pinned in `mise.toml` and `mise.lock`. Install them with [mise](https://mise.jdx.dev): - -```sh -mise install --locked -``` - -Then: +Workflows are linted with [actionlint](https://github.com/rhysd/actionlint), which also runs [shellcheck](https://github.com/koalaman/shellcheck) on inline `run:` scripts. Shell scripts committed to the repository (`*.sh`, e.g. under `scripts/`) are linted with shellcheck directly. Formatting is checked with `prettier --check`. Run all linters with: ```sh mise run lint ``` -CI runs the same command on every pull request and on every push to `main`. +`mise run verify-all` includes this step. ## Updating dependencies diff --git a/mise.toml b/mise.toml index 55b72d8..b7b2656 100644 --- a/mise.toml +++ b/mise.toml @@ -8,21 +8,39 @@ lockfile = true "npm:prettier" = "3.9.8" [tasks.format] +description = "Format files with prettier" run = "prettier --write ." [tasks."update-checksums"] +description = "Format, then regenerate each workflow's workflow-sha256 file" run = "scripts/compute-workflow-sha256.sh" depends = ["format"] +[tasks."check-checksums"] +description = "Check that workflow-sha256 files match their workflows" +run = "scripts/compute-workflow-sha256.sh --check" + +[tasks."check-release-please-config"] +description = "Validate release-please-config.json (components, key order)" +run = "scripts/check-release-please-config.sh" + [tasks."lint:format"] +description = "Check formatting with prettier" run = "prettier --check ." [tasks."lint:actionlint"] +description = "Lint GitHub Actions workflows with actionlint" run = "actionlint" [tasks."lint:shellcheck"] +description = "Lint shell scripts with shellcheck" shell = "bash -euo pipefail -c" run = "git ls-files -z --cached --others --exclude-standard '*.sh' | xargs -0 -r shellcheck" [tasks.lint] +description = "Run all linters" depends = [ "lint:format", "lint:actionlint", "lint:shellcheck" ] + +[tasks."verify-all"] +description = "Run all lints and checks (as in CI)" +depends = [ "lint", "check-checksums", "check-release-please-config"]