Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/ci_nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,15 @@ jobs:
matrix:
include:
- name: stability
init_flags: "--curio latesttag:pdp/v* --filecoin-services latesttag:v*"
issue_label: scenarios-run-stability
issue_title: "FOC Devnet scenarios run report (stability)"
- name: frontier
init_flags: "--curio gitbranch:main --filecoin-services gitbranch:main"
issue_label: scenarios-run-frontier
issue_title: "FOC Devnet scenarios run report (frontier)"
uses: ./.github/workflows/ci_run.yml
with:
name: ${{ matrix.name }}
init_flags: ${{ matrix.init_flags }}
profile: ${{ matrix.name }}
# Reporting is always on for scheduled runs; for manual dispatch it follows the input.
enable_reporting: ${{ github.event_name == 'schedule' || inputs.reporting == true }}
# On scheduled runs, such as nightly `inputs.skip_report_on_pass` is absent (empty string), so we cannot rely
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci_pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Runs on every pull request targeting main, and on every merge to main.
#
# Executes lint checks, cargo tests, and a single CI run with the default
# config (no special init_flags). Issue reporting is disabled — that is
# dependency profile. Issue reporting is disabled — that is
# reserved for the nightly schedule run.

name: CI (Pull Request)
Expand Down Expand Up @@ -58,6 +58,6 @@ jobs:
uses: ./.github/workflows/ci_run.yml
with:
name: default
init_flags: ''
profile: default
enable_reporting: false
secrets: inherit
93 changes: 55 additions & 38 deletions .github/workflows/ci_run.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
# Called by ci_pull_request.yml (default config, no reporting) and
# ci_nightly.yml (stability / frontier matrix, issue reporting enabled).
#
# The only behavioural difference between callers is the `init_flags` input,
# which controls which versions of Curio / filecoin-services are used.
# The dependency profile controls the versions of compatibility-sensitive
# server and client components used by the run.

name: CI Run

Expand All @@ -16,11 +16,10 @@ on:
description: 'Human-readable run name (e.g. default, stability, frontier)'
required: true
type: string
init_flags:
description: 'Extra flags forwarded to `foc-devnet init`'
required: false
profile:
description: 'Dependency profile: default, stability, or frontier'
required: true
type: string
default: ''
enable_reporting:
description: 'When true, file a GitHub issue with the scenario report'
required: false
Expand Down Expand Up @@ -123,22 +122,27 @@ jobs:
rm -rf target/
df -h

# Compute cache keys based on version info and source files
# - CODE_HASH: Changes when Lotus/Curio versions change (for build artifacts cache)
# - DOCKER_HASH: Changes when Dockerfiles change (for Docker images cache)
- name: "CHECK: {Compute version hashes}"
id: version-hashes
run: |
# Get version output
VERSION_OUTPUT=$(./foc-devnet version 2>&1)

# Compute CODE_HASH from Lotus/Curio versions only (filecoin-services contains contracts/scripts
# that are compiled by Foundry at deploy time, not compiled into Lotus/Curio binaries)
CODE_HASH=$(echo "$VERSION_OUTPUT" | grep -E 'default:code:(lotus|curio)' | sha256sum | cut -d' ' -f1)
echo "code-hash=$CODE_HASH" >> $GITHUB_OUTPUT
echo "CODE_HASH: $CODE_HASH"

# Compute DOCKER_HASH from docker/ directory (Dockerfile changes)
# Dependency profile resolution queries npm release metadata.
- name: "EXEC: {Setup Node.js}, independent"
uses: actions/setup-node@v4
with:
node-version: 'lts/*'

- name: "CHECK: {Resolve dependency profile}"
id: dependencies
run: |
METADATA="$RUNNER_TEMP/ci-dependencies.json"
python3 scripts/resolve-ci-dependencies.py resolve \
--profile '${{ inputs.profile }}' \
--output "$METADATA" \
--github-output "$GITHUB_OUTPUT" \
--github-env "$GITHUB_ENV"

# Docker images do not contain Lotus/Curio binaries, so their cache identity
# depends only on the Docker build inputs.
- name: "CHECK: {Compute Docker hash}"
id: docker-hash
run: |
DOCKER_HASH=$(find docker -type f -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
echo "docker-hash=$DOCKER_HASH" >> $GITHUB_OUTPUT
echo "DOCKER_HASH: $DOCKER_HASH"
Expand All @@ -150,7 +154,7 @@ jobs:
uses: actions/cache/restore@v4
with:
path: ~/.docker-images-cache
key: ${{ runner.os }}-docker-images-${{ steps.version-hashes.outputs.docker-hash }}
key: ${{ runner.os }}-docker-images-${{ steps.docker-hash.outputs.docker-hash }}

# CACHE-DOCKER: If Docker images are cached, load them from tarballs
- name: "EXEC: {Load Docker images}, DEP: {C-docker-images-cache}"
Expand All @@ -174,14 +178,14 @@ jobs:
if: steps.cache-docker-images.outputs.cache-hit == 'true'
run: |
./foc-devnet clean --all
./foc-devnet init --no-docker-build ${{ inputs.init_flags }}
./foc-devnet init --no-docker-build ${{ steps.dependencies.outputs.init-args }}

# If Docker images are not cached, do full init (downloads YugabyteDB and builds all images)
- name: "EXEC: {Initialize without cache}, independent"
if: steps.cache-docker-images.outputs.cache-hit != 'true'
run: |
./foc-devnet clean --all
./foc-devnet init ${{ inputs.init_flags }}
./foc-devnet init ${{ steps.dependencies.outputs.init-args }}

# CACHE-DOCKER: Save Docker images as tarballs for caching
- name: "EXEC: {Save Docker images for cache}, DEP: {C-docker-images-cache}"
Expand All @@ -204,15 +208,25 @@ jobs:
uses: actions/cache/save@v4
with:
path: ~/.docker-images-cache
key: ${{ runner.os }}-docker-images-${{ steps.version-hashes.outputs.docker-hash }}
key: ${{ runner.os }}-docker-images-${{ steps.docker-hash.outputs.docker-hash }}

# Verify the exact repositories cloned by init and derive source-based cache
# identities. filecoin-services is intentionally excluded because it does
# not contribute to the Lotus/Curio binaries.
- name: "CHECK: {Verify dependency checkouts}"
id: verified-dependencies
run: |
python3 scripts/resolve-ci-dependencies.py verify \
--metadata "$CI_DEPENDENCY_METADATA" \
--github-output "$GITHUB_OUTPUT"

# CACHE-BINARIES: Try to restore previously built Lotus/Curio binaries
- name: "CACHE_RESTORE: {C-build-artifacts-cache}"
id: cache-binaries
uses: actions/cache/restore@v4
with:
path: ~/.foc-devnet/bin
key: ${{ runner.os }}-binaries-${{ inputs.name }}-${{ steps.version-hashes.outputs.code-hash }}
key: ${{ runner.os }}-binaries-${{ steps.verified-dependencies.outputs.source-hash }}

- name: "EXEC: {Ensure permissions on binaries}, DEP: {C-build-artifacts-cache}"
if: steps.cache-binaries.outputs.cache-hit == 'true'
Expand All @@ -225,9 +239,9 @@ jobs:
uses: actions/cache/restore@v4
with:
path: ~/.foc-devnet/docker/volumes/cache/foc-builder
key: ${{ runner.os }}-foc-builder-cache-${{ inputs.name }}-${{ hashFiles('docker/**') }}-${{ hashFiles('src/config.rs') }}
key: ${{ runner.os }}-foc-builder-cache-${{ steps.verified-dependencies.outputs.go-cache-key }}-${{ hashFiles('docker/**') }}-${{ hashFiles('src/config.rs') }}
restore-keys: |
${{ runner.os }}-foc-builder-cache-${{ inputs.name }}-
${{ runner.os }}-foc-builder-cache-${{ steps.verified-dependencies.outputs.go-cache-key }}-

- name: "EXEC: {Ensure permissions}, DEP: {C-foc-builder-cache}"
if: steps.cache-binaries.outputs.cache-hit != 'true' &&
Expand All @@ -253,15 +267,15 @@ jobs:
uses: actions/cache/save@v4
with:
path: ~/.foc-devnet/docker/volumes/cache/foc-builder
key: ${{ runner.os }}-foc-builder-cache-${{ inputs.name }}-${{ hashFiles('docker/**') }}-${{ hashFiles('src/config.rs') }}
key: ${{ runner.os }}-foc-builder-cache-${{ steps.verified-dependencies.outputs.go-cache-key }}-${{ hashFiles('docker/**') }}-${{ hashFiles('src/config.rs') }}

# CACHE-BINARIES: Save built Lotus/Curio binaries for future runs
- name: "CACHE_SAVE: {C-build-artifacts-cache}"
if: steps.cache-binaries.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ~/.foc-devnet/bin
key: ${{ runner.os }}-binaries-${{ inputs.name }}-${{ steps.version-hashes.outputs.code-hash }}
key: ${{ runner.os }}-binaries-${{ steps.verified-dependencies.outputs.source-hash }}

# Disk free-up
- name: "EXEC: {Clean up Go modules}, DEP: {C-build-artifacts-cache}"
Expand Down Expand Up @@ -336,6 +350,7 @@ jobs:
# Verify cluster is running correctly
- name: "EXEC: {Check cluster status}, independent"
if: always()
continue-on-error: true
run: ./foc-devnet status

- name: "EXEC: {List foc-* containers}, independent"
Expand All @@ -353,13 +368,6 @@ jobs:
echo "✓ devnet-info.json created"
jq '.version' "$DEVNET_INFO"

# Setup Node.js for JavaScript examples
- name: "EXEC: {Setup Node.js}, independent"
if: steps.start_cluster.outcome == 'success'
uses: actions/setup-node@v4
with:
node-version: 'lts/*'

# Setup pnpm (required by scenario tests)
- name: "EXEC: {Setup pnpm}, independent"
if: steps.start_cluster.outcome == 'success'
Expand Down Expand Up @@ -439,6 +447,15 @@ jobs:
echo '```'
./foc-devnet version 2>&1 || echo "version command failed"
echo '```'
echo ""
echo "## Resolved dependencies"
if [ -f "$CI_DEPENDENCY_METADATA" ]; then
echo '```json'
cat "$CI_DEPENDENCY_METADATA"
echo '```'
else
echo "Dependency metadata is unavailable."
fi
} > "$REPORT"
fi

Expand Down
7 changes: 7 additions & 0 deletions README_ADVANCED.md
Original file line number Diff line number Diff line change
Expand Up @@ -1327,3 +1327,10 @@ Reports are written to `~/.foc-devnet/state/latest/scenario_report.md`.

Scenarios run automatically in CI after the devnet starts. On nightly runs (or manual dispatch with `reporting` enabled), failures automatically create a GitHub issue with a full report.

CI resolves compatibility-sensitive dependencies from `ci/dependency-profiles.json`.
Pull requests use the pinned `default` profile, while nightly `stability` runs use
the latest final releases and nightly `frontier` runs pin current development
branch heads to immutable commits. The resolved metadata path is exposed to
scenarios as `CI_DEPENDENCY_METADATA`; Synapse SDK and filecoin-pin also receive
their exact source, version/ref, and commit through `SYNAPSE_SDK_*` and
`FILECOIN_PIN_*` environment variables.
83 changes: 83 additions & 0 deletions ci/dependency-profiles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"schema_version": 1,
"components": {
"lotus": {
"kind": "git",
"repository": "https://github.com/filecoin-project/lotus.git",
"default": {
"strategy": "config_default"
},
"stability": {
"strategy": "latest_stable_tag",
"tag_pattern": "v*"
},
"frontier": {
"strategy": "branch",
"branch": "master"
}
},
"curio": {
"kind": "git",
"repository": "https://github.com/filecoin-project/curio.git",
"default": {
"strategy": "config_default"
},
"stability": {
"strategy": "latest_stable_tag",
"tag_pattern": "pdp/v*"
},
"frontier": {
"strategy": "branch",
"branch": "main"
}
},
"filecoin-services": {
"kind": "git",
"repository": "https://github.com/FilOzone/filecoin-services.git",
"default": {
"strategy": "config_default"
},
"stability": {
"strategy": "latest_stable_tag",
"tag_pattern": "v*"
},
"frontier": {
"strategy": "branch",
"branch": "main"
}
},
"synapse-sdk": {
"kind": "git_client",
"repository": "https://github.com/FilOzone/synapse-sdk.git",
"npm_package": "@filoz/synapse-sdk",
"default": {
"strategy": "commit",
"commit": "fadc836e65804311aca3bd2276861acabe42313f"
},
"stability": {
"strategy": "npm_latest_tag",
"tag_prefix": "synapse-sdk-v"
},
"frontier": {
"strategy": "branch",
"branch": "master"
}
},
"filecoin-pin": {
"kind": "npm_client",
"repository": "https://github.com/filecoin-project/filecoin-pin.git",
"npm_package": "filecoin-pin",
"default": {
"strategy": "npm_version",
"version": "0.22.3"
},
"stability": {
"strategy": "npm_latest"
},
"frontier": {
"strategy": "branch",
"branch": "master"
}
}
}
}
Loading
Loading