Skip to content
Closed
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
36 changes: 18 additions & 18 deletions .github/workflows/anchor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ concurrency:
env:
SOLANA_VERSION: '1.18.26'
ANCHOR_VERSION: '0.30.1'
RUST_VERSION: '1.79'
RUST_VERSION: '1.85'
NODE_VERSION: '20'

# ══════════════════════════════════════════════════════════════════
Expand All @@ -56,10 +56,10 @@ jobs:
toolchain: ${{ env.RUST_VERSION }}
components: clippy, rustfmt

- name: Setup Solana
uses: metadaoproject/setup-solana@v1
with:
solana-cli-version: ${{ env.SOLANA_VERSION }}
- name: Install Solana CLI
run: |
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"
echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH

- name: Install Anchor CLI
run: npm install -g @coral-xyz/anchor-cli@${{ env.ANCHOR_VERSION }}
Expand Down Expand Up @@ -131,10 +131,10 @@ jobs:
with:
toolchain: ${{ env.RUST_VERSION }}

- name: Setup Solana
uses: metadaoproject/setup-solana@v1
with:
solana-cli-version: ${{ env.SOLANA_VERSION }}
- name: Install Solana CLI
run: |
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"
echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH

- name: Install Anchor CLI
run: npm install -g @coral-xyz/anchor-cli@${{ env.ANCHOR_VERSION }}
Expand Down Expand Up @@ -191,10 +191,10 @@ jobs:
toolchain: ${{ env.RUST_VERSION }}
components: clippy, rustfmt

- name: Setup Solana
uses: metadaoproject/setup-solana@v1
with:
solana-cli-version: ${{ env.SOLANA_VERSION }}
- name: Install Solana CLI
run: |
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"
echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH

- name: Install Anchor CLI
run: npm install -g @coral-xyz/anchor-cli@${{ env.ANCHOR_VERSION }}
Expand Down Expand Up @@ -266,10 +266,10 @@ jobs:
with:
toolchain: ${{ env.RUST_VERSION }}

- name: Setup Solana
uses: metadaoproject/setup-solana@v1
with:
solana-cli-version: ${{ env.SOLANA_VERSION }}
- name: Install Solana CLI
run: |
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"
echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH

- name: Install Anchor CLI
run: npm install -g @coral-xyz/anchor-cli@${{ env.ANCHOR_VERSION }}
Expand Down Expand Up @@ -358,7 +358,7 @@ jobs:
continue-on-error: true

- name: Install cargo-audit
run: cargo install cargo-audit --quiet
run: cargo install cargo-audit --locked --quiet

- name: Security audit β€” bounty-registry
working-directory: contracts/bounty-registry
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/solfoundry-bounty-poster.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: SolFoundry Bounty Poster

on:
issues:
types: [labeled, opened, edited]
schedule:
- cron: '0 9 * * *'
workflow_dispatch:
inputs:
dry_run:
description: 'Dry run mode (no actual posting)'
required: false
default: 'false'

jobs:
post-bounties:
runs-on: ubuntu-latest
permissions:
issues: read
contents: write # Needed for tracking file

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Post bounties to SolFoundry
uses: ./actions/bounty-poster
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
solfoundry-api-key: ${{ secrets.SOLFOUNDRY_API_KEY }}
bounty-label: 'bounty'
reward-amount: '100000'
reward-tier: 'T2'
dry-run: ${{ github.event.inputs.dry_run || 'false' }}

- name: Commit tracking file
if: always()
run: |
if [ -f .solfoundry-bounties-posted.json ]; then
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .solfoundry-bounties-posted.json
git diff --cached --quiet || git commit -m "chore: update bounty tracking [skip ci]"
git push || echo "No changes to push"
fi
257 changes: 257 additions & 0 deletions actions/bounty-poster/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
# @file README.md
# @brief Documentation for SolFoundry Bounty Poster GitHub Action
# @author BountyClaw
# @version 1.0.0
#
# @description
# Comprehensive documentation for the SolFoundry Bounty Poster GitHub Action,
# which automatically converts labeled GitHub issues into SolFoundry bounties.

# SolFoundry Bounty Poster GitHub Action

Automatically convert labeled GitHub issues into SolFoundry bounties with customizable reward amounts and tiers.

## Overview

This GitHub Action enables repository maintainers to automatically post bounties to the SolFoundry platform when issues are tagged with a specific label. It streamlines the bounty creation process by extracting issue details and posting them to SolFoundry with minimal configuration.

## Features

- **Label-based Detection**: Automatically detects issues with bounty labels
- **Customizable Rewards**: Configure reward amounts and tiers per workflow
- **Multi-Tier Support**: Supports T1, T2, T3 bounty tiers with different requirements
- **Issue Linking**: Automatically links back to original GitHub issues
- **Zero Configuration**: Works out of the box with sensible defaults
- **Batch Processing**: Handles multiple bounty issues in a single run

## Requirements

- GitHub repository with issue tracking enabled
- SolFoundry account with API access
- GitHub Actions enabled on the repository

## Installation

### Step 1: Get SolFoundry API Key

1. Visit [SolFoundry Developer Portal](https://solfoundry.dev/developer)
2. Sign in or create an account
3. Navigate to API Keys section
4. Generate a new API key with bounty posting permissions
5. Copy the key for use in GitHub Secrets

### Step 2: Add GitHub Secret

1. Go to your repository on GitHub
2. Navigate to **Settings** β†’ **Secrets and variables** β†’ **Actions**
3. Click **New repository secret**
4. Name: `SOLFOUNDRY_API_KEY`
5. Value: Your SolFoundry API key from Step 1
6. Click **Add secret**

### Step 3: Create Bounty Label

1. Go to your repository β†’ **Issues** β†’ **Labels**
2. Click **New label**
3. Name: `bounty` (or your preferred label name)
4. Color: Choose a distinctive color (e.g., green `#0E8A16`)
5. Description: "Issues eligible for SolFoundry bounties"
6. Click **Create label**

### Step 4: Create Workflow

Create `.github/workflows/solfoundry-bounty-poster.yml`:

```yaml
# @file solfoundry-bounty-poster.yml
# @brief Workflow for automatic bounty posting
# @description Triggers bounty creation when issues are labeled or on schedule

name: SolFoundry Bounty Poster

on:
# Trigger when issues are labeled
issues:
types: [labeled, opened, edited]

# Run daily at 9 AM UTC to catch any missed issues
schedule:
- cron: '0 9 * * *'

# Allow manual trigger for testing
workflow_dispatch:
inputs:
bounty_label:
description: 'Label to scan for bounties'
required: false
default: 'bounty'
reward_amount:
description: 'Reward amount in $FNDRY'
required: false
default: '100000'
Comment on lines +82 to +91
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Manual-dispatch docs diverge from the repository’s actual workflow trigger schema.

At Line 83-92, the README documents workflow_dispatch.inputs (bounty_label, reward_amount) and then consumes them at Line 114-115.
But the actual workflow context (.github/workflows/solfoundry-bounty-poster.yml, Line 3-8) shows a bare workflow_dispatch: with no inputs. This means the documented/manual-trigger contract in README does not match the checked-in workflow and can mislead operators about configurable run-time parameters.

Also applies to: 114-115

πŸ€– Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@actions/bounty-poster/README.md` around lines 83 - 92, The README documents
workflow_dispatch inputs (bounty_label, reward_amount) but the actual workflow
(solfoundry-bounty-poster.yml) has a bare workflow_dispatch with no inputs, so
reconcile them by either adding the documented inputs under workflow_dispatch in
solfoundry-bounty-poster.yml (declare bounty_label and reward_amount with
appropriate description/defaults) or removing/adjusting the input usage from
README.md so it matches the current bare workflow_dispatch; update references to
bounty_label and reward_amount wherever they are consumed to reflect the chosen
approach.


jobs:
post-bounties:
# Use Ubuntu latest runner
runs-on: ubuntu-latest

# Required permissions for issue reading
permissions:
issues: read
contents: read

steps:
# Checkout repository code
- name: Checkout repository
uses: actions/checkout@v4

# Run the bounty poster action
- name: Post bounties to SolFoundry
uses: SolFoundry/solfoundry/actions/bounty-poster@main
with:
solfoundry-api-key: ${{ secrets.SOLFOUNDRY_API_KEY }}
bounty-label: ${{ github.event.inputs.bounty_label || 'bounty' }}
reward-amount: ${{ github.event.inputs.reward_amount || '100000' }}
reward-tier: 'T2'
```

## Configuration

### Inputs

| Input | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `solfoundry-api-key` | string | βœ… Yes | - | Your SolFoundry API key for authentication |
| `bounty-label` | string | ❌ No | `bounty` | Label that triggers bounty creation |
| `reward-amount` | string | ❌ No | `100000` | Reward amount in $FNDRY tokens |
| `reward-tier` | string | ❌ No | `T1` | Bounty tier (T1, T2, T3) |


### Outputs

| Output | Type | Description |
|--------|------|-------------|
| `bounty-ids` | string | Comma-separated list of created bounty IDs |
| `bounty-urls` | string | Comma-separated list of bounty URLs |
| `posted-count` | number | Number of bounties posted |
| `skipped-count` | number | Number of issues skipped (already posted) |

### Bounty Tiers

| Tier | Reward Range | Requirements | Use Case |
|------|-------------|--------------|----------|
| **T1** | 50K - 200K $FNDRY | Open to all contributors | Simple bugs, documentation fixes |
| **T2** | 200K - 500K $FNDRY | Requires 1 merged T1 bounty | Feature implementations |
| **T3** | 500K - 1M+ $FNDRY | Requires 3 merged T2 bounties | Complex features, architecture work |

## Usage Examples

### Basic Usage

```yaml
- uses: SolFoundry/solfoundry/actions/bounty-poster@main
with:
solfoundry-api-key: ${{ secrets.SOLFOUNDRY_API_KEY }}
```

### With Custom Label

```yaml
- uses: SolFoundry/solfoundry/actions/bounty-poster@main
with:
solfoundry-api-key: ${{ secrets.SOLFOUNDRY_API_KEY }}
bounty-label: 'reward'
reward-amount: '50000'
```

### Tier-Based Workflows

```yaml
# High-priority bounties
- name: Post high-priority bounties
uses: SolFoundry/solfoundry/actions/bounty-poster@main
with:
solfoundry-api-key: ${{ secrets.SOLFOUNDRY_API_KEY }}
bounty-label: 'bounty-high'
reward-amount: '500000'
reward-tier: 'T2'

# Standard bounties
- name: Post standard bounties
uses: SolFoundry/solfoundry/actions/bounty-poster@main
with:
solfoundry-api-key: ${{ secrets.SOLFOUNDRY_API_KEY }}
bounty-label: 'bounty'
reward-amount: '100000'
reward-tier: 'T1'
```

## Creating a Bounty Issue

To create a bounty-eligible issue:

1. Create a new issue with a clear title and description
2. Add acceptance criteria as a checklist
3. Apply the bounty label (e.g., `bounty`)
4. The action will automatically detect and post it

### Example Issue Template

```markdown
## Description
Implement user authentication with JWT tokens.

## Acceptance Criteria
- [ ] Login endpoint with email/password
- [ ] JWT token generation
- [ ] Token refresh mechanism
- [ ] Password reset flow

## Reward
50000 $FNDRY
```

## Troubleshooting

### "No issues found with label"

- Ensure the label exists in your repository
- Check that issues with the label are open (not closed)
- Verify the label name matches exactly (case-sensitive)

### "API key invalid"

- Verify your `SOLFOUNDRY_API_KEY` secret is set correctly
- Check that the API key hasn't expired
- Ensure the key has bounty posting permissions

### Action not triggering

- Verify the workflow file is in `.github/workflows/`
- Check the YAML syntax is valid
- Ensure the workflow is enabled in the Actions tab

## Security Considerations

- Store your SolFoundry API key as a GitHub Secret
- Never commit API keys to your repository
- Use repository-level secrets rather than organization-level for fine-grained control
- Rotate API keys periodically

## License

MIT License - see LICENSE file for details.

## Contributing

Contributions welcome! Please see our [Contributing Guide](../../CONTRIBUTING.md).

## Support

- [SolFoundry Documentation](https://docs.solfoundry.dev)
- [GitHub Issues](https://github.com/SolFoundry/solfoundry/issues)
- [Discord Community](https://discord.gg/solfoundry)

---

*Built with ❀️ by the SolFoundry community*
Loading
Loading