Skip to content

Commit f9dd6c6

Browse files
feat: add GitHub Actions workflow for web3telegram dapp deployment
- Add dapp-deploy.yml workflow with sconify and deployment steps - Update deployment-dapp scripts to work with GitHub Actions - Replace DRONE_DEPLOY_TO with DEPLOY_ENVIRONMENT - Add support for pre-computed checksums from sconify workflow - Remove legacy Drone CI support from deployment scripts - Configure workflow to use public Docker registry and production sconify images
1 parent cad1c39 commit f9dd6c6

File tree

8 files changed

+309
-115
lines changed

8 files changed

+309
-115
lines changed

.github/workflows/dapp-deploy.yml

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
name: Deploy DApp Contract
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
environment:
7+
description: 'Deployment environment'
8+
required: true
9+
type: choice
10+
options:
11+
- dapp-dev
12+
- dapp-prod
13+
image-tag:
14+
description: 'Tag for the dapp image to sconify'
15+
required: true
16+
type: string
17+
default: 'latest'
18+
sconify-version:
19+
description: 'Version of the sconify image to use'
20+
type: string
21+
default: '5.7.6-v15'
22+
23+
env:
24+
DEPLOY_ENVIRONMENT: ${{ inputs.environment }}
25+
26+
jobs:
27+
sconify:
28+
uses: iExecBlockchainComputing/github-actions-workflows/.github/workflows/[email protected]
29+
with:
30+
image-name: product/web3telegram-dapp
31+
image-tag: ${{ inputs.image-tag }}
32+
sconify-debug: false
33+
sconify-prod: true
34+
docker-registry: docker.io
35+
sconify-version: ${{ inputs.sconify-version }}
36+
binary: /usr/local/bin/node
37+
command: node /app/src/app.js
38+
host-path: |
39+
/etc/hosts
40+
/etc/resolv.conf
41+
binary-fs: true
42+
fs-dir: /app
43+
heap: 1G
44+
dlopen: 1
45+
mprotect: 1
46+
docker-username: ${{ vars.DOCKERHUB_USERNAME }}
47+
scontain-username: ${{ secrets.SCONTAIN_REGISTRY_USERNAME }}
48+
secrets:
49+
docker-password: ${{ secrets.DOCKERHUB_PAT }}
50+
scontain-password: ${{ secrets.SCONTAIN_REGISTRY_PAT }}
51+
scone-signing-key: ${{ secrets.SCONIFY_SIGNING_PRIVATE_KEY }}
52+
53+
display-sconify-results:
54+
runs-on: ubuntu-latest
55+
needs: sconify
56+
steps:
57+
- name: Display Sconify Results
58+
run: |
59+
echo "## Sconify Results" >> $GITHUB_STEP_SUMMARY
60+
echo "" >> $GITHUB_STEP_SUMMARY
61+
62+
echo "### Production Image" >> $GITHUB_STEP_SUMMARY
63+
echo "- **Image**: ${{ needs.sconify.outputs.prod-image }}" >> $GITHUB_STEP_SUMMARY
64+
echo "- **Checksum**: ${{ needs.sconify.outputs.prod-checksum }}" >> $GITHUB_STEP_SUMMARY
65+
echo "- **MrEnclave**: ${{ needs.sconify.outputs.prod-mrenclave }}" >> $GITHUB_STEP_SUMMARY
66+
echo "" >> $GITHUB_STEP_SUMMARY
67+
68+
echo "### Summary" >> $GITHUB_STEP_SUMMARY
69+
echo "Sconification completed successfully!" >> $GITHUB_STEP_SUMMARY
70+
71+
deploy-dapp:
72+
runs-on: ubuntu-latest
73+
needs: sconify
74+
steps:
75+
- name: Checkout code
76+
uses: actions/checkout@v4
77+
78+
- name: Setup Node.js
79+
uses: actions/setup-node@v4
80+
with:
81+
node-version: '18.19'
82+
cache: 'npm'
83+
84+
- name: Install dependencies
85+
run: |
86+
npm ci
87+
cd node_modules/whitelist-smart-contract
88+
npm install --save-dev ts-node
89+
cd ../../deployment-dapp
90+
npm ci
91+
92+
- name: Create scone fingerprint file
93+
run: |
94+
MRENCLAVE="${{ needs.sconify.outputs.prod-mrenclave }}"
95+
echo "$MRENCLAVE" > deployment-dapp/.scone-fingerprint
96+
97+
- name: Deploy dapp contract
98+
env:
99+
DEPLOY_ENVIRONMENT: ${{ inputs.environment }}
100+
WALLET_PRIVATE_KEY_DEV: ${{ secrets.WEB3TELEGRAM_DAPP_OWNER_DEV_PRIVATEKEY }}
101+
WALLET_PRIVATE_KEY_PROD: ${{ secrets.WEB3TELEGRAM_DAPP_OWNER_PROD_PRIVATEKEY }}
102+
DOCKER_IMAGE_CHECKSUM_DEV: ${{ needs.sconify.outputs.prod-checksum }}
103+
DOCKER_IMAGE_CHECKSUM_PROD: ${{ needs.sconify.outputs.prod-checksum }}
104+
run: |
105+
cd deployment-dapp
106+
npm run deploy-dapp
107+
108+
- name: Push dapp secret
109+
env:
110+
DEPLOY_ENVIRONMENT: ${{ inputs.environment }}
111+
WALLET_PRIVATE_KEY_DEV: ${{ secrets.WEB3TELEGRAM_DAPP_OWNER_DEV_PRIVATEKEY }}
112+
WALLET_PRIVATE_KEY_PROD: ${{ secrets.WEB3TELEGRAM_DAPP_OWNER_PROD_PRIVATEKEY }}
113+
TELEGRAM_BOT_TOKEN_DEV: ${{ secrets.TELEGRAM_BOT_TOKEN_DEV }}
114+
TELEGRAM_BOT_TOKEN_PROD: ${{ secrets.TELEGRAM_BOT_TOKEN_PROD }}
115+
run: |
116+
cd deployment-dapp
117+
npm run push-dapp-secret
118+
119+
- name: Publish free sell order
120+
env:
121+
DEPLOY_ENVIRONMENT: ${{ inputs.environment }}
122+
WALLET_PRIVATE_KEY_DEV: ${{ secrets.WEB3TELEGRAM_DAPP_OWNER_DEV_PRIVATEKEY }}
123+
WALLET_PRIVATE_KEY_PROD: ${{ secrets.WEB3TELEGRAM_DAPP_OWNER_PROD_PRIVATEKEY }}
124+
PRICE: '0'
125+
VOLUME: '1000000000'
126+
run: |
127+
cd deployment-dapp
128+
npm run publish-sell-order
129+
130+
- name: Add resource to whitelist (dev)
131+
if: inputs.environment == 'dapp-dev'
132+
env:
133+
WALLET_PRIVATE_KEY: ${{ secrets.DEPLOYER_DEV_PRIVATEKEY }}
134+
CONTRACT_ADDRESS: ${{ secrets.WEB3TELEGRAM_WHITELIST_DEV_ADDRESS }}
135+
run: |
136+
cd node_modules/whitelist-smart-contract
137+
export ADDRESS_TO_ADD=$(cat ../../deployment-dapp/.app-address) && npm run addResourceToWhitelist
138+
139+
- name: Add resource to whitelist (prod)
140+
if: inputs.environment == 'dapp-prod'
141+
env:
142+
WALLET_PRIVATE_KEY: ${{ secrets.DEPLOYER_PROD_PRIVATEKEY }}
143+
CONTRACT_ADDRESS: ${{ secrets.WEB3TELEGRAM_WHITELIST_PROD_ADDRESS }}
144+
run: |
145+
cd node_modules/whitelist-smart-contract
146+
export ADDRESS_TO_ADD=$(cat ../../deployment-dapp/.app-address) && npm run addResourceToWhitelist
147+
148+
- name: Configure ENS
149+
env:
150+
DEPLOY_ENVIRONMENT: ${{ inputs.environment }}
151+
WALLET_PRIVATE_KEY_DEV: ${{ secrets.WEB3TELEGRAM_DAPP_OWNER_DEV_PRIVATEKEY }}
152+
WALLET_PRIVATE_KEY_PROD: ${{ secrets.WEB3TELEGRAM_DAPP_OWNER_PROD_PRIVATEKEY }}
153+
run: |
154+
cd deployment-dapp
155+
npm run configure-ens
156+
157+
- name: Upload deployment artifacts
158+
uses: actions/upload-artifact@v4
159+
with:
160+
name: deployment-artifacts
161+
path: |
162+
deployment-dapp/.app-address
163+
deployment-dapp/.scone-fingerprint

deployment-dapp/src/config/config.ts

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,19 @@ const dappVersion = JSON.parse(
2727
export const DOCKER_IMAGE_NAMESPACE = 'iexechub';
2828
export const DOCKER_IMAGE_REPOSITORY = 'web3telegram-dapp';
2929
export const DOCKER_IMAGE_PROD_TAG = `${dappVersion}-sconify-${SCONIFIER_VERSION}-production`;
30-
export const DOCKER_IMAGE_DEV_TAG = `dev-${process.env.DRONE_COMMIT}-sconify-${SCONIFIER_VERSION}-production`;
30+
export const DOCKER_IMAGE_DEV_TAG = `dev-${
31+
process.env.GITHUB_SHA || 'latest'
32+
}-sconify-${SCONIFIER_VERSION}-production`;
3133

32-
//drone target
33-
export const DRONE_TARGET_DEPLOY_DEV = 'dapp-dev';
34-
export const DRONE_TARGET_DEPLOY_PROD = 'dapp-prod';
35-
export const DRONE_TARGET_SELL_ORDER_DEV = 'dapp-publish-sell-order-dev';
36-
export const DRONE_TARGET_SELL_ORDER_PROD = 'dapp-publish-sell-order-prod';
37-
export const DRONE_TARGET_REVOKE_SELL_ORDER_DEV = 'dapp-revoke-sell-order-dev';
38-
export const DRONE_TARGET_REVOKE_SELL_ORDER_PROD =
34+
//deployment targets for GitHub Actions
35+
export const DEPLOY_TARGET_DEV = 'dapp-dev';
36+
export const DEPLOY_TARGET_PROD = 'dapp-prod';
37+
export const DEPLOY_TARGET_SELL_ORDER_DEV = 'dapp-publish-sell-order-dev';
38+
export const DEPLOY_TARGET_SELL_ORDER_PROD = 'dapp-publish-sell-order-prod';
39+
export const DEPLOY_TARGET_REVOKE_SELL_ORDER_DEV = 'dapp-revoke-sell-order-dev';
40+
export const DEPLOY_TARGET_REVOKE_SELL_ORDER_PROD =
3941
'dapp-revoke-sell-order-prod';
40-
export const DRONE_TARGET_PUSH_SECRET_DEV = 'dapp-push-secret-dev';
41-
export const DRONE_TARGET_PUSH_SECRET_PROD = 'dapp-push-secret-prod';
42-
export const DRONE_TARGET_CONFIGURE_ENS_DEV = 'configure-ens-dev';
43-
export const DRONE_TARGET_CONFIGURE_ENS_PROD = 'configure-ens-prod';
42+
export const DEPLOY_TARGET_PUSH_SECRET_DEV = 'dapp-push-secret-dev';
43+
export const DEPLOY_TARGET_PUSH_SECRET_PROD = 'dapp-push-secret-prod';
44+
export const DEPLOY_TARGET_CONFIGURE_ENS_DEV = 'configure-ens-dev';
45+
export const DEPLOY_TARGET_CONFIGURE_ENS_PROD = 'configure-ens-prod';

deployment-dapp/src/configureEnsNameScript.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,57 @@
11
import {
2-
DRONE_TARGET_CONFIGURE_ENS_DEV,
3-
DRONE_TARGET_CONFIGURE_ENS_PROD,
4-
DRONE_TARGET_DEPLOY_DEV,
5-
DRONE_TARGET_DEPLOY_PROD,
2+
DEPLOY_TARGET_CONFIGURE_ENS_DEV,
3+
DEPLOY_TARGET_CONFIGURE_ENS_PROD,
4+
DEPLOY_TARGET_DEV,
5+
DEPLOY_TARGET_PROD,
66
WEB3_TELEGRAM_ENS_NAME_DEV,
77
WEB3_TELEGRAM_ENS_NAME_PROD,
88
} from './config/config.js';
99
import { getIExec, loadAppAddress } from './utils/utils.js';
1010
import { configureEnsName } from './singleFunction/configureEnsName.js';
1111

1212
const main = async () => {
13-
// get env variables from drone
13+
// get env variables from GitHub Actions
1414
const {
15-
DRONE_DEPLOY_TO,
15+
DEPLOY_ENVIRONMENT,
1616
WALLET_PRIVATE_KEY_DEV,
1717
WALLET_PRIVATE_KEY_PROD,
1818
DEPLOYED_APP_ADDRESS, // if already deployed in a previous step and want to configure ENS promoting configure-ens pipeline
1919
ENS_NAME,
2020
} = process.env;
2121

22+
const deployTarget = DEPLOY_ENVIRONMENT;
23+
2224
if (
23-
!DRONE_DEPLOY_TO ||
24-
(DRONE_DEPLOY_TO !== DRONE_TARGET_DEPLOY_DEV &&
25-
DRONE_DEPLOY_TO !== DRONE_TARGET_DEPLOY_PROD &&
26-
DRONE_DEPLOY_TO !== DRONE_TARGET_CONFIGURE_ENS_DEV &&
27-
DRONE_DEPLOY_TO !== DRONE_TARGET_CONFIGURE_ENS_PROD)
25+
!deployTarget ||
26+
(deployTarget !== DEPLOY_TARGET_DEV &&
27+
deployTarget !== DEPLOY_TARGET_PROD &&
28+
deployTarget !== DEPLOY_TARGET_CONFIGURE_ENS_DEV &&
29+
deployTarget !== DEPLOY_TARGET_CONFIGURE_ENS_PROD)
2830
)
29-
throw Error(`Invalid promote target ${DRONE_DEPLOY_TO}`);
31+
throw Error(`Invalid promote target ${deployTarget}`);
3032

3133
const appAddress = DEPLOYED_APP_ADDRESS ?? (await loadAppAddress()); // use ALREADY_DEPLOYED_APP_ADDRESS when promoting configure-ens pipeline
3234
let privateKey;
3335
let ensName;
3436
if (
35-
DRONE_DEPLOY_TO === DRONE_TARGET_DEPLOY_DEV ||
36-
DRONE_DEPLOY_TO === DRONE_TARGET_CONFIGURE_ENS_DEV
37+
deployTarget === DEPLOY_TARGET_DEV ||
38+
deployTarget === DEPLOY_TARGET_CONFIGURE_ENS_DEV
3739
) {
3840
privateKey = WALLET_PRIVATE_KEY_DEV;
3941
ensName = ENS_NAME ?? WEB3_TELEGRAM_ENS_NAME_DEV;
4042
} else if (
41-
DRONE_DEPLOY_TO === DRONE_TARGET_DEPLOY_PROD ||
42-
DRONE_DEPLOY_TO === DRONE_TARGET_CONFIGURE_ENS_PROD
43+
deployTarget === DEPLOY_TARGET_PROD ||
44+
deployTarget === DEPLOY_TARGET_CONFIGURE_ENS_PROD
4345
) {
4446
privateKey = WALLET_PRIVATE_KEY_PROD;
4547
ensName = ENS_NAME ?? WEB3_TELEGRAM_ENS_NAME_PROD;
4648
}
4749

4850
if (!privateKey)
49-
throw Error(`Failed to get privateKey for target ${DRONE_DEPLOY_TO}`);
51+
throw Error(`Failed to get privateKey for target ${deployTarget}`);
5052

5153
if (!ensName)
52-
throw Error(`Failed to get ens name for target ${DRONE_DEPLOY_TO}`);
54+
throw Error(`Failed to get ens name for target ${deployTarget}`);
5355

5456
const iexec = getIExec(privateKey);
5557

deployment-dapp/src/deployScript.ts

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,64 @@ import { deployApp } from './singleFunction/deployApp.js';
22
import {
33
DOCKER_IMAGE_DEV_TAG,
44
DOCKER_IMAGE_PROD_TAG,
5-
DRONE_TARGET_DEPLOY_DEV,
6-
DRONE_TARGET_DEPLOY_PROD,
5+
DEPLOY_TARGET_DEV,
6+
DEPLOY_TARGET_PROD,
77
} from './config/config.js';
88
import { getIExec, saveAppAddress } from './utils/utils.js';
99

1010
const main = async () => {
11-
// get env variables from drone
12-
const { DRONE_DEPLOY_TO, WALLET_PRIVATE_KEY_DEV, WALLET_PRIVATE_KEY_PROD } =
13-
process.env;
11+
// get env variables from GitHub Actions
12+
const {
13+
DEPLOY_ENVIRONMENT,
14+
WALLET_PRIVATE_KEY_DEV,
15+
WALLET_PRIVATE_KEY_PROD,
16+
DOCKER_IMAGE_CHECKSUM_DEV,
17+
DOCKER_IMAGE_CHECKSUM_PROD,
18+
} = process.env;
19+
20+
const deployTarget = DEPLOY_ENVIRONMENT;
1421

1522
if (
16-
!DRONE_DEPLOY_TO ||
17-
(DRONE_DEPLOY_TO !== DRONE_TARGET_DEPLOY_DEV &&
18-
DRONE_DEPLOY_TO !== DRONE_TARGET_DEPLOY_PROD)
23+
!deployTarget ||
24+
(deployTarget !== DEPLOY_TARGET_DEV && deployTarget !== DEPLOY_TARGET_PROD)
1925
)
20-
throw Error(`Invalid promote target ${DRONE_DEPLOY_TO}`);
26+
throw Error(`Invalid promote target ${deployTarget}`);
2127

2228
let privateKey;
23-
if (DRONE_DEPLOY_TO === DRONE_TARGET_DEPLOY_DEV) {
29+
let checksum;
30+
if (deployTarget === DEPLOY_TARGET_DEV) {
2431
privateKey = WALLET_PRIVATE_KEY_DEV;
25-
} else if (DRONE_DEPLOY_TO === DRONE_TARGET_DEPLOY_PROD) {
32+
checksum = DOCKER_IMAGE_CHECKSUM_DEV;
33+
} else if (deployTarget === DEPLOY_TARGET_PROD) {
2634
privateKey = WALLET_PRIVATE_KEY_PROD;
35+
checksum = DOCKER_IMAGE_CHECKSUM_PROD;
2736
}
2837

2938
if (!privateKey)
30-
throw Error(`Failed to get privateKey for target ${DRONE_DEPLOY_TO}`);
39+
throw Error(`Failed to get privateKey for target ${deployTarget}`);
3140

3241
const iexec = getIExec(privateKey);
3342

3443
let dockerImageTag;
35-
if (DRONE_DEPLOY_TO === DRONE_TARGET_DEPLOY_DEV) {
44+
if (deployTarget === DEPLOY_TARGET_DEV) {
3645
dockerImageTag = DOCKER_IMAGE_DEV_TAG;
37-
} else if (DRONE_DEPLOY_TO === DRONE_TARGET_DEPLOY_PROD) {
46+
} else if (deployTarget === DEPLOY_TARGET_PROD) {
3847
dockerImageTag = DOCKER_IMAGE_PROD_TAG;
3948
}
4049

50+
console.log(`Deploying with environment: ${deployTarget}`);
51+
console.log(`Using image tag: ${dockerImageTag}`);
52+
if (checksum) {
53+
console.log(`Using pre-computed checksum: ${checksum}`);
54+
} else {
55+
console.log('Fetching checksum from Docker Hub...');
56+
}
57+
4158
//deploy app
4259
const address = await deployApp({
4360
iexec,
4461
dockerTag: dockerImageTag,
62+
checksum,
4563
});
4664
await saveAppAddress(address);
4765
};

0 commit comments

Comments
 (0)