Saltar al contenido
mypipelines
Contracts (Hardhat/Solidity)·Reusable workflow·on: workflow_call

Contracts Build

Contracts - Build & Compile

.github/workflows/contracts-build.yml

.github/workflows/contracts-build.yml
name: Contracts - Build & Compile
on:
workflow_call:
inputs:
runner:
description: 'Runner type'
required: false
type: string
default: 'ubuntu-latest'
container_image:
description: >-
Run the job inside this image (e.g.
ghcr.io/codehunters-io/ci-base-images:1.0.0-node). Empty = plain
runner with actions/setup-node. A container already carrying the
toolchain skips the per-run Node download and pins the version to
the tag.
required: false
type: string
default: ''
node_version:
description: 'Node.js version (ignored when container_image is set)'
required: false
type: string
default: '20'
package_manager:
description: 'Package manager (npm, yarn, or pnpm)'
required: false
type: string
default: 'pnpm'
pnpm_version:
description: 'pnpm version (used when package_manager: pnpm)'
required: false
type: string
default: '10'
run_size_check:
description: 'Run hardhat-contract-sizer (strict mode fails if any contract > 24KB)'
required: false
type: boolean
default: true
artifact_retention_days:
description: 'Days to retain compiled artifacts'
required: false
type: number
default: 1
outputs:
artifact_name:
description: 'Name of uploaded build artifact'
value: ${{ jobs.build.outputs.artifact_name }}
# Least privilege for what this workflow actually does. Without it the
# job inherits whatever the calling repository's default happens to be,
# which on older repositories is write-all.
permissions:
contents: read
packages: read
jobs:
build:
name: Build & Compile
runs-on: ${{ inputs.runner }}
# `container:` takes an object or nothing at all, and there is no way to
# write "no container" as a string. fromJSON('null') is how you say it.
container: ${{ inputs.container_image != '' && fromJSON(format('{{"image":"{0}"}}', inputs.container_image)) || fromJSON('null') }}
timeout-minutes: 15
outputs:
artifact_name: contracts-build-${{ github.run_id }}
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup pnpm
if: inputs.package_manager == 'pnpm' && inputs.container_image == ''
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- name: Setup Node.js ${{ inputs.node_version }}
if: inputs.container_image == ''
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ inputs.node_version }}
cache: ${{ inputs.package_manager }}
- name: Report toolchain (container)
if: inputs.container_image != ''
run: |
echo "Container: ${{ inputs.container_image }}"
node --version
npm --version
- name: Install dependencies
run: |
case "${{ inputs.package_manager }}" in
pnpm) pnpm install --frozen-lockfile ;;
yarn) yarn install --frozen-lockfile ;;
*) npm ci ;;
esac
- name: Compile contracts
run: |
case "${{ inputs.package_manager }}" in
pnpm) pnpm hardhat compile ;;
yarn) yarn hardhat compile ;;
*) npx hardhat compile ;;
esac
echo "### Hardhat Compile" >> $GITHUB_STEP_SUMMARY
echo "**Status:** Passed" >> $GITHUB_STEP_SUMMARY
- name: Contract size check
if: inputs.run_size_check
run: |
case "${{ inputs.package_manager }}" in
pnpm) pnpm hardhat size-contracts ;;
yarn) yarn hardhat size-contracts ;;
*) npx hardhat size-contracts ;;
esac
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Contract Sizes" >> $GITHUB_STEP_SUMMARY
echo "Strict mode enabled (24KB EIP-170 limit)." >> $GITHUB_STEP_SUMMARY
- name: Upload compiled artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: contracts-build-${{ github.run_id }}
path: |
artifacts/
cache/
typechain-types/
retention-days: ${{ inputs.artifact_retention_days }}
if-no-files-found: warn