Skip to content

Commit ff63488

Browse files
committed
initial commit
0 parents  commit ff63488

File tree

37 files changed

+7049
-0
lines changed

37 files changed

+7049
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: "Build Anchor"
2+
description: "Build Anchor"
3+
inputs:
4+
testing:
5+
description: "Whether to run tests"
6+
required: false
7+
default: "true"
8+
devnet:
9+
description: "Whether to build for devnet"
10+
required: false
11+
default: "false"
12+
program:
13+
description: "Program to build"
14+
required: true
15+
runs:
16+
using: "composite"
17+
steps:
18+
- uses: ./.github/actions/setup/
19+
- uses: ./.github/actions/setup-solana/
20+
- uses: ./.github/actions/setup-anchor/
21+
- name: Build Program
22+
shell: bash
23+
run: |
24+
echo "Building Anchor program: ${{ inputs.program }} to get IDL"
25+
anchor build -p ${{ inputs.program }}
26+
- name: Copy artifacts from container
27+
shell: bash
28+
run: |
29+
mkdir -p ./build-artifacts/so
30+
mkdir -p ./build-artifacts/idl
31+
32+
echo "Current working directory: $(pwd)"
33+
echo "Listing target directory:"
34+
ls -la target/deploy/
35+
ls -la target/idl/
36+
37+
# Direct copy without using Docker commands
38+
cp -v target/deploy/${{ inputs.program }}.so ./build-artifacts/so/
39+
cp -v target/idl/${{ inputs.program }}.json ./build-artifacts/idl/
40+
41+
echo "Checking copied files:"
42+
ls -la ./build-artifacts/so/
43+
ls -la ./build-artifacts/idl/
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: "Build Verified"
2+
description: "Builds a Solana program using solana-verify"
3+
inputs:
4+
devnet:
5+
description: "Whether to use devnet feature"
6+
required: false
7+
default: "false"
8+
testing:
9+
description: "Whether to use devnet feature"
10+
required: false
11+
default: "false"
12+
program:
13+
description: "The program to build and upload"
14+
required: true
15+
program-id:
16+
description: "The program id of the program we are uploading"
17+
required: true
18+
verify-version:
19+
description: "Version of solana-verify to use"
20+
required: true
21+
22+
runs:
23+
using: "composite"
24+
steps:
25+
- uses: ./.github/actions/setup/
26+
- uses: ./.github/actions/setup-anchor/
27+
- uses: ./.github/actions/setup-solana-verify/
28+
with:
29+
verify-version: ${{ inputs.verify-version }}
30+
31+
# Add Docker socket mounting
32+
- name: Setup Docker
33+
shell: bash
34+
run: |
35+
sudo chmod 666 /var/run/docker.sock
36+
37+
- name: Build Verified
38+
shell: bash
39+
run: |
40+
FEATURES=""
41+
if [ "${{ inputs.devnet }}" = "true" ]; then
42+
FEATURES="--features devnet"
43+
fi
44+
# Run solana-verify directly without Docker
45+
~/.cargo/bin/solana-verify build --library-name ${{ inputs.program }} -- $FEATURES

.github/actions/deploy/action.yaml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: "Deploy Program"
2+
description: "Deploy program to Solana network"
3+
inputs:
4+
program:
5+
description: "Program name"
6+
required: true
7+
program-id:
8+
description: "Program ID"
9+
required: true
10+
network:
11+
description: "The Solana network URL"
12+
required: true
13+
keypair:
14+
description: "Base58 encoded keypair for deployment (optional)"
15+
required: false
16+
skip-build:
17+
description: "Skip building the program"
18+
required: false
19+
default: "false"
20+
21+
runs:
22+
using: "composite"
23+
steps:
24+
- uses: ./.github/actions/setup/
25+
- uses: ./.github/actions/setup-solana/
26+
27+
- name: Build Program
28+
if: inputs.skip-build != 'true'
29+
uses: ./.github/actions/build-anchor/
30+
with:
31+
program: ${{ inputs.program }}
32+
devnet: ${{ contains(inputs.network, 'devnet') }}
33+
34+
- name: Setup Network and Deploy
35+
shell: bash
36+
run: |
37+
# Setup keypair
38+
if [ ! -z "${{ inputs.keypair }}" ]; then
39+
echo "Using provided keypair"
40+
echo "${{ inputs.keypair }}" > keypair.json
41+
elif [[ "${{ inputs.network }}" == *"mainnet"* ]]; then
42+
echo "Using mainnet deployer keypair"
43+
echo "$MAINNET_DEPLOYER_KEYPAIR" > keypair.json
44+
else
45+
echo "Using devnet deployer keypair"
46+
echo "$DEVNET_DEPLOYER_KEYPAIR" > keypair.json
47+
fi
48+
solana config set --keypair keypair.json
49+
50+
# Deploy program
51+
if ! solana program show ${{ inputs.program-id }} -u ${{ inputs.network }}; then
52+
echo "Program not found, using PROGRAM_ADDRESS_KEYPAIR for initial deployment"
53+
echo "$PROGRAM_ADDRESS_KEYPAIR" > program-keypair.json
54+
solana program deploy \
55+
--program-id program-keypair.json \
56+
target/deploy/${{ inputs.program }}.so \
57+
--with-compute-unit-price 10000 \
58+
--max-sign-attempts 1000 \
59+
--use-rpc \
60+
-u ${{ inputs.network }}
61+
else
62+
echo "Program exists, upgrading program ${{ inputs.program-id }}"
63+
solana program write-buffer target/deploy/${{ inputs.program }}.so \
64+
--with-compute-unit-price 10000 \
65+
--max-sign-attempts 1000 \
66+
--use-rpc \
67+
-u ${{ inputs.network }}
68+
BUFFER=$(solana program show --buffers -u ${{ inputs.network }} | grep Buffer | cut -d ' ' -f1 | tail -n1)
69+
solana program set-buffer-authority --new-buffer-authority $(solana address) $BUFFER -u ${{ inputs.network }}
70+
solana program upgrade \
71+
target/deploy/${{ inputs.program }}.so \
72+
--program-id ${{ inputs.program-id }} \
73+
--with-compute-unit-price 10000 \
74+
--max-sign-attempts 1000 \
75+
--use-rpc \
76+
-u ${{ inputs.network }}
77+
fi
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: "Extract Versions"
2+
description: "Extracts Solana and Anchor versions from Cargo.lock"
3+
outputs:
4+
solana_version:
5+
description: "Detected Solana version"
6+
value: ${{ steps.extract.outputs.solana_version }}
7+
anchor_version:
8+
description: "Detected Anchor version"
9+
value: ${{ steps.extract.outputs.anchor_version }}
10+
11+
runs:
12+
using: "composite"
13+
steps:
14+
- id: extract
15+
shell: bash
16+
run: |
17+
# Extract Solana version from Cargo.lock or use override
18+
if [ -n "${{ github.event.inputs.solana_version }}" ]; then
19+
SOLANA_VERSION="${{ github.event.inputs.solana_version }}"
20+
echo "Using override Solana version: ${SOLANA_VERSION}"
21+
else
22+
SOLANA_VERSION=$(grep -A 2 'name = "solana-program"' Cargo.lock | grep 'version' | head -n 1 | cut -d'"' -f2)
23+
echo "Detected Solana version: ${SOLANA_VERSION}"
24+
fi
25+
echo "solana_version=${SOLANA_VERSION}" >> $GITHUB_OUTPUT
26+
echo "SOLANA_VERSION=${SOLANA_VERSION}" >> $GITHUB_ENV
27+
echo "SOLANA_CLI_VERSION=${SOLANA_VERSION}" >> $GITHUB_ENV
28+
29+
# Extract Anchor version from Cargo.lock or use override
30+
if [ -n "${{ github.event.inputs.anchor_version }}" ]; then
31+
ANCHOR_VERSION="${{ github.event.inputs.anchor_version }}"
32+
echo "Using override Anchor version: ${ANCHOR_VERSION}"
33+
else
34+
ANCHOR_VERSION=$(grep -A 2 'name = "anchor-lang"' Cargo.lock | grep 'version' | head -n 1 | cut -d'"' -f2)
35+
echo "Detected Anchor version: ${ANCHOR_VERSION}"
36+
fi
37+
echo "anchor_version=${ANCHOR_VERSION}" >> $GITHUB_OUTPUT
38+
echo "ANCHOR_VERSION=${ANCHOR_VERSION}" >> $GITHUB_ENV
39+
40+
# Debug environment variables
41+
echo "=== Environment Variables Debug ==="
42+
echo "Content of GITHUB_ENV file:"
43+
cat $GITHUB_ENV
44+
echo "=== Direct Environment Variables ==="
45+
echo "SOLANA_VERSION: $SOLANA_VERSION"
46+
echo "ANCHOR_VERSION: $ANCHOR_VERSION"
47+
echo "==========================="
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: "Upload IDL"
2+
description: "Uploads an anchor program IDL"
3+
inputs:
4+
program-id:
5+
description: "The program id of the program we are uploading"
6+
required: true
7+
rpc-url:
8+
description: "The Solana network"
9+
required: true
10+
keypair:
11+
description: "The keypair to use for deploys"
12+
required: true
13+
idl-buffer:
14+
description: "The IDL buffer address from buffer deploy"
15+
required: true
16+
17+
runs:
18+
using: "composite"
19+
steps:
20+
- uses: ./.github/actions/setup/
21+
- uses: ./.github/actions/setup-anchor/
22+
- run: echo "$DEPLOY_KEYPAIR" > ./deploy-keypair.json && chmod 600 ./deploy-keypair.json
23+
shell: bash
24+
env:
25+
DEPLOY_KEYPAIR: ${{ inputs.keypair }}
26+
27+
- name: Upload IDL
28+
uses: nick-invision/retry@v2
29+
with:
30+
timeout_minutes: 10
31+
max_attempts: 50
32+
shell: bash
33+
command: |
34+
echo "Checking if IDL exists for program ${{ inputs.program-id }}"
35+
if ! anchor idl fetch ${{ inputs.program-id }} --provider.cluster ${{ inputs.rpc-url }} > /dev/null 2>&1; then
36+
echo "IDL not found, initializing..."
37+
anchor idl init --filepath ./target/idl/${{ env.PROGRAM_NAME }}.json ${{ inputs.program-id }} --provider.cluster ${{ inputs.rpc-url }} --provider.wallet ./deploy-keypair.json
38+
else
39+
echo "IDL found, setting buffer..."
40+
anchor idl set-buffer --buffer ${{ inputs.idl-buffer }} ${{ inputs.program-id }} --provider.cluster ${{ inputs.rpc-url }} --provider.wallet ./deploy-keypair.json
41+
fi
42+
43+
- run: rm ./deploy-keypair.json
44+
shell: bash
45+
if: always()
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: "Program Upgrade"
2+
description: "Upgrades or deploys a Solana program"
3+
inputs:
4+
program-id:
5+
description: "Program ID to upgrade"
6+
required: true
7+
program:
8+
description: "Program name"
9+
required: true
10+
buffer:
11+
description: "Buffer address"
12+
required: true
13+
rpc-url:
14+
description: "Solana RPC URL"
15+
required: true
16+
keypair:
17+
description: "Deployer keypair"
18+
required: true
19+
program-keypair:
20+
description: "Program address keypair for initial deployment"
21+
required: true
22+
23+
runs:
24+
using: "composite"
25+
steps:
26+
- uses: ./.github/actions/setup/
27+
- uses: ./.github/actions/setup-solana/
28+
29+
- name: Write keypairs
30+
shell: bash
31+
run: |
32+
echo "$DEPLOY_KEYPAIR" > ./deploy-keypair.json && chmod 600 ./deploy-keypair.json
33+
echo "$PROGRAM_KEYPAIR" > ./program-keypair.json && chmod 600 ./program-keypair.json
34+
env:
35+
DEPLOY_KEYPAIR: ${{ inputs.keypair }}
36+
PROGRAM_KEYPAIR: ${{ inputs.program-keypair }}
37+
38+
- name: Check if program exists
39+
id: check-program
40+
shell: bash
41+
run: |
42+
if solana program show ${{ inputs.program-id }} --url ${{ inputs.rpc-url }} 2>&1 | grep -q "Data Length:"; then
43+
echo "exists=true" >> $GITHUB_OUTPUT
44+
else
45+
echo "exists=false" >> $GITHUB_OUTPUT
46+
fi
47+
48+
- name: Deploy new program
49+
if: steps.check-program.outputs.exists == 'false'
50+
uses: nick-invision/retry@v2
51+
with:
52+
timeout_minutes: 10
53+
max_attempts: 3
54+
command: |
55+
solana program deploy \
56+
--url ${{ inputs.rpc-url }} \
57+
--keypair ./deploy-keypair.json \
58+
--program-id ./program-keypair.json \
59+
--max-sign-attempts 50 \
60+
--with-compute-unit-price 100000 \
61+
--use-rpc \
62+
./target/deploy/${{ inputs.program }}.so
63+
64+
- name: Upgrade existing program
65+
if: steps.check-program.outputs.exists == 'true'
66+
uses: nick-invision/retry@v2
67+
with:
68+
timeout_minutes: 10
69+
max_attempts: 3
70+
command: |
71+
echo "Debug: Buffer value is '${{ inputs.buffer }}'"
72+
if [ -z "${{ inputs.buffer }}" ]; then
73+
echo "Error: No buffer provided"
74+
exit 1
75+
fi
76+
77+
# Get current and new program sizes
78+
CURRENT_SIZE=$(solana program show "${{ inputs.program-id }}" -u "${{ inputs.rpc-url }}" | grep "Data Length:" | cut -d ":" -f2 | cut -d " " -f2)
79+
NEW_SIZE=$(wc -c < "./target/deploy/${{ inputs.program }}.so")
80+
echo "Current program size: $CURRENT_SIZE bytes"
81+
echo "New program size: $NEW_SIZE bytes"
82+
83+
# Extend program if needed
84+
if [ $NEW_SIZE -gt $CURRENT_SIZE ]; then
85+
echo "Program needs to be extended"
86+
solana program extend "${{ inputs.program-id }}" $((NEW_SIZE - CURRENT_SIZE)) -u "${{ inputs.rpc-url }}" -k ./deploy-keypair.json
87+
echo "Program extended successfully"
88+
fi
89+
90+
# Upgrade program
91+
solana program upgrade "${{ inputs.buffer }}" "${{ inputs.program-id }}" -k ./deploy-keypair.json -u "${{ inputs.rpc-url }}"
92+
93+
env:
94+
BUFFER: ${{ inputs.buffer }}
95+
PROGRAM_ID: ${{ inputs.program-id }}
96+
PROGRAM: ${{ inputs.program }}
97+
RPC_URL: ${{ inputs.rpc-url }}
98+
99+
- name: Cleanup
100+
if: always()
101+
shell: bash
102+
run: |
103+
rm -f ./deploy-keypair.json
104+
rm -f ./program-keypair.json

0 commit comments

Comments
 (0)