This repository contains a comprehensive collection of reusable GitHub Action workflows designed to streamline CI/CD, security, testing, and operational processes across Story Protocol projects.
To use any of these workflows in your repository:
jobs:
my-job:
uses: storyprotocol/gha-workflows/.github/workflows/<workflow-filename>@main
with:
# workflow inputs
secrets:
# workflow secrets
General-purpose workflows for common operations.
Workflow | Purpose | Key Features | When to Use |
---|---|---|---|
reusable-timestamp.yml | Generate timestamps in specific timezones | β’ Configurable timezone β’ Environment variable output β’ Useful for versioning |
Creating time-based identifiers, logging execution times |
reusable-lint-go-workflow.yml | Lint Go code with golangci-lint | β’ Configurable Go version β’ 5-minute timeout β’ Latest golangci-lint |
Ensuring Go code quality in PRs and main branch |
reusable-slack-notifs.yml | Send formatted Slack notifications | β’ Rich message formatting β’ Optional image support β’ Markdown support |
Build notifications, deployment alerts, failure alerts |
Build, test, and deployment workflows for various platforms and technologies.
Workflow | Purpose | Key Features | When to Use |
---|---|---|---|
reusable-ecr-build-push.yml | Build and push Go API Docker images to AWS ECR | β’ OIDC authentication β’ Go test execution β’ Trivy scanning β’ SHA + latest tags |
Deploying Go API services to AWS |
reusable-ecr-build-push-temporal-worker.yml | Build and push Temporal worker images to AWS ECR | β’ Custom image tags β’ OIDC authentication β’ Temporal-specific Dockerfile |
Deploying Temporal workers to AWS |
reusable-gcp-image-build-worker.yml | Build and push Docker images to GCP Container Registry | β’ Environment-aware β’ Flexible Dockerfile paths β’ Environment variables support |
Deploying containerized apps to GCP |
reusable-gcp-app-release-publisher.yml | Publish release messages to GCP Pub/Sub | β’ Triggers deployments β’ Environment mapping β’ Structured JSON messages |
Triggering GCP deployments via Pub/Sub |
Workflow | Purpose | Key Features | When to Use |
---|---|---|---|
reusable-build-test-workflow.yml | Full build and test for Node.js projects | β’ Mochawesome reports β’ GitHub Pages deployment β’ Test artifacts |
Comprehensive testing with visual reports |
reusable-build-unit-test-workflow.yml | Unit testing for Node.js projects | β’ Fast execution β’ No report generation β’ PR-friendly |
Quick unit test validation |
reusable-build-integration-test-workflow.yml | Integration testing for Node.js projects | β’ Isolated integration tests β’ Environment-specific |
Testing external integrations |
reusable-build-python-unit-test-workflow.yml | Unit testing for Python projects | β’ Multi-version testing β’ Coverage reports β’ Virtual environments |
Python service testing |
reusable-build-python-integration-test-workflow.yml | Integration testing for Python projects | β’ pytest-based β’ Coverage included β’ RPC testing support |
Python integration validation |
Workflow | Purpose | Key Features | When to Use |
---|---|---|---|
reusable-create-release.yml | Create GitHub releases with changelogs | β’ Automated changelog β’ Tag creation β’ Previous tag detection |
Creating versioned releases |
Security scanning, access management, and infrastructure security workflows.
Workflow | Purpose | Key Features | When to Use |
---|---|---|---|
reusable-secrets-scanning.yml | Scan for hardcoded secrets with TruffleHog | β’ Verified secrets only β’ Slack notifications β’ Configurable depth |
Preventing secret leaks |
secrets-scanning.yml | Automatic secrets scanning on main branch | β’ Auto-triggers on push β’ Calls reusable workflow |
Continuous security monitoring |
scorecards.yml | OSSF Scorecards security assessment | β’ SARIF format output β’ Code scanning integration β’ Manual trigger |
Security posture assessment |
Workflow | Purpose | Key Features | When to Use |
---|---|---|---|
reusable-fetch-bastion-ips.yml | Fetch bastion host IP addresses | β’ Multi-environment β’ Conditional fetching β’ EC2 tag filtering |
Getting bastion IPs for access |
reusable-fetch-network-node-ips.yml | Fetch all network node IPs across regions | β’ Multi-region support β’ Bulk IP retrieval β’ Node metadata |
Network-wide IP discovery |
reusable-fetch-security-group-ids.yml | Fetch security group IDs | β’ Multi-region β’ Bastion + network SGs β’ Region mapping |
Dynamic SG management |
reusable-parse-bastion-access-files.yml | Parse YAML access configs to JSON | β’ YAML to JSON conversion β’ IP permissions format β’ Multi-environment |
Preparing access rules |
reusable-update-security-groups.yml | Update security groups with new IPs | β’ Bulk updates β’ Status tracking β’ Multi-region |
Adding access rules |
reusable-revoke-inbound-rules.yml | Revoke all inbound rules from SGs | β’ Clean slate approach β’ Multi-region β’ Conditional execution |
Resetting security groups |
reusable-remove-gha-ip-from-sg.yml | Remove GitHub Actions runner IPs | β’ Cleanup automation β’ Multi-SG support β’ Security hygiene |
Post-deployment cleanup |
Quality assurance and code coverage workflows.
Workflow | Purpose | Key Features | When to Use |
---|---|---|---|
reusable-forge-code-coverage.yml | Generate code coverage for Solidity contracts | β’ Foundry/Forge integration β’ lcov + HTML reports β’ Path exclusion β’ Branch coverage |
Smart contract test coverage |
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
jobs:
lint:
uses: storyprotocol/gha-workflows/.github/workflows/reusable-lint-go-workflow.yml@main
with:
go-version: '1.22'
test:
uses: storyprotocol/gha-workflows/.github/workflows/reusable-build-test-workflow.yml@main
with:
sha: ${{ github.sha }}
ENVIRONMENT: staging
secrets:
WALLET_PRIVATE_KEY: ${{ secrets.WALLET_PRIVATE_KEY }}
TEST_WALLET_ADDRESS: ${{ secrets.TEST_WALLET_ADDRESS }}
security-scan:
uses: storyprotocol/gha-workflows/.github/workflows/reusable-secrets-scanning.yml@main
with:
branch: ${{ github.ref_name }}
secrets:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
SLACK_CHANNEL_ID_GITHUB_NOTIFICATION: ${{ secrets.SLACK_CHANNEL_ID }}
build-and-push:
needs: [lint, test, security-scan]
if: github.ref == 'refs/heads/main'
uses: storyprotocol/gha-workflows/.github/workflows/reusable-ecr-build-push.yml@main
with:
ecr-repo: "my-api-service"
ecr-repo-aws-region: "us-east-1"
secrets:
AWS_ACCOUNT: ${{ secrets.AWS_ACCOUNT }}
AWS_ACCOUNT_TARGET: ${{ secrets.AWS_ACCOUNT_TARGET }}
notify:
needs: [build-and-push]
if: always()
uses: storyprotocol/gha-workflows/.github/workflows/reusable-slack-notifs.yml@main
with:
title: ${{ needs.build-and-push.result == 'success' && 'β
Deployment Successful' || 'β Deployment Failed' }}
short-desc: 'Build ${{ github.sha }} has ${{ needs.build-and-push.result }}'
img-alt-text: 'Build status'
secrets:
channel-name: ${{ secrets.SLACK_CHANNEL_ID }}
slack-bot-token: ${{ secrets.SLACK_BOT_TOKEN }}
name: Update Bastion Access
on:
push:
paths:
- 'configs/bastion-access-*.yaml'
jobs:
parse-configs:
uses: storyprotocol/gha-workflows/.github/workflows/reusable-parse-bastion-access-files.yml@main
with:
devnet_file: "configs/bastion-access-devnet.yaml"
testnet_file: "configs/bastion-access-testnet.yaml"
fetch-sg-ids:
uses: storyprotocol/gha-workflows/.github/workflows/reusable-fetch-security-group-ids.yml@main
with:
role_to_assume: ${{ secrets.AWS_ROLE }}
aws_region: "us-east-1"
# ... other inputs
revoke-existing:
needs: [fetch-sg-ids]
uses: storyprotocol/gha-workflows/.github/workflows/reusable-revoke-inbound-rules.yml@main
with:
sg_ids_devnet: ${{ needs.fetch-sg-ids.outputs.security_group_ids_devnet }}
# ... other inputs
update-sgs:
needs: [parse-configs, fetch-sg-ids, revoke-existing]
uses: storyprotocol/gha-workflows/.github/workflows/reusable-update-security-groups.yml@main
with:
ips_devnet: ${{ needs.parse-configs.outputs.ips_devnet }}
sg_ids_devnet: ${{ needs.fetch-sg-ids.outputs.security_group_ids_devnet }}
# ... other inputs
name: Multi-Environment Tests
on: [push, pull_request]
jobs:
unit-tests:
strategy:
matrix:
environment: [staging, production]
uses: storyprotocol/gha-workflows/.github/workflows/reusable-build-unit-test-workflow.yml@main
with:
sha: ${{ github.sha }}
ENVIRONMENT: ${{ matrix.environment }}
secrets:
WALLET_PRIVATE_KEY: ${{ secrets[format('WALLET_PRIVATE_KEY_{0}', matrix.environment)] }}
TEST_WALLET_ADDRESS: ${{ secrets[format('TEST_WALLET_ADDRESS_{0}', matrix.environment)] }}
-
Version Pinning: All workflows use pinned action versions with SHA hashes for security. Regularly update these after security review.
-
Secret Management:
- Use environment-specific secrets
- Pass secrets explicitly through the
secrets
context - Never hardcode sensitive information
-
Conditional Execution: Many workflows support conditional execution based on environment changes. Use this to optimize CI/CD time.
-
Error Handling: Most workflows will fail fast on errors. Consider using
if: always()
for cleanup or notification steps. -
Documentation: Each workflow has its own documentation in the
docs/
directory. Keep these updated when modifying workflows.
- GitHub Actions must be enabled in your repository
- Appropriate secrets must be configured at the repository or organization level
- For AWS workflows: OIDC provider must be configured
- For GCP workflows: Service account keys must be available
- For Slack workflows: Slack app with bot token must be configured
When adding new reusable workflows:
- Follow the naming convention:
reusable-<purpose>.yml
- Include comprehensive input validation
- Use pinned action versions with SHA hashes
- Create documentation in
docs/<category>/readme-reusable-<name>.md
- Update this README with the new workflow information
- Test thoroughly in a separate repository before merging
- All workflows use pinned action versions for security
- Secrets are handled through GitHub's encrypted secrets
- AWS workflows use OIDC for temporary credentials
- Regular security scanning with TruffleHog and OSSF Scorecards
[Include your license information here]