diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6a7ef44 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,13 @@ +**/.husky +**/.idea +**/.vscode +**/node_modules +**/.env +.dockerignore +**/.gitignore +**/*.env +**/.git +**/.gitmodules +**/.github +**/Dockerfile +**/docker-compose.yml \ No newline at end of file diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml new file mode 100644 index 0000000..b840799 --- /dev/null +++ b/.github/workflows/build_and_deploy.yml @@ -0,0 +1,52 @@ +#Location: .github/workflows/custom_config.yml + +name: Build and push containers to Github Container Registry and apply rolling update +on: + push: + branches: + - staging + - develop + - main + tags: + - v* + +jobs: + build: + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Getting image tag + uses: actions/github-script@v6 + id: get_image_tag + with: + result-encoding: string + script: | + return context.payload.ref.replace(/.*\//, ''); + + - name: Create and push docker image + run: | + # login to ghcr.io + docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + + # build with full metadata + docker build \ + --label "org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY}" \ + --label "org.opencontainers.image.description=Deposit payment example dockerized app" \ + --label "org.opencontainers.image.licenses=MIT" \ + -t ghcr.io/golemfactory/deposit_example:${{ steps.get_image_tag.outputs.result }} \ + --build-arg BACKEND_URL=http://deposit.dev.golem.network:5174 \ + . + + # push one image with two tags into repository + docker push --all-tags ghcr.io/golemfactory/deposit_example + + - name: Notify Staging + continue-on-error: true + if: ${{ steps.get_image_tag.outputs.result == 'staging' }} + run: curl http://deposit.dev.golem.network:5000/release/pull \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f01233c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,40 @@ +name: Build docker files + +on: + push: + +permissions: + packages: write + contents: write + +jobs: + + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Create and push docker image + run: | + # login to ghcr.io + docker login ghcr.io -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} + + # build with full metadata + docker build \ + --label "org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY}" \ + --label "org.opencontainers.image.description=Deposit payment example dockerized app" \ + --label "org.opencontainers.image.licenses=MIT" \ + -t ghcr.io/golemfactory/deposit_example:latest \ + --build-arg BACKEND_URL=http://deposit.dev.golem.network:5174 \ + . + + # push one image with two tags into repository + docker push --all-tags ghcr.io/golemfactory/deposit_example + + - name: Notify Develop Server + continue-on-error: true + if: ${{ steps.get_image_tag.outputs.result == 'develop' }} + run: curl http://deposit.dev.golem.network.:5000/release/pull diff --git a/.gitignore b/.gitignore index ea8b570..6b12b77 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules dist backend/.env.local temp +.env \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 5bfa6b8..a16a3e3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,13 +1,13 @@ [submodule "golem-js"] path = golem-js - url = git@github.com:golemfactory/golem-js.git + url = https://github.com/golemfactory/golem-js.git branch = pociej/deposit [submodule "ya-ts-client"] path = ya-ts-client - url = git@github.com:golemfactory/ya-ts-client.git + url = https://github.com/golemfactory/ya-ts-client.git branch = pociej/deposit [submodule "golem-sdk-task-executor"] path = golem-sdk-task-executor - url = git@github.com:golemfactory/golem-sdk-task-executor.git + url = https://github.com/golemfactory/golem-sdk-task-executor.git branch = pociej/deposit diff --git a/.husky/commit-msg b/.husky/commit-msg deleted file mode 100755 index 1d46fee..0000000 --- a/.husky/commit-msg +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -print_error() { - echo -e "\033[0;31m$1\033[0m" # \033[0;31m sets text color to red, \033[0m resets color -} - -commit_msg_file=".git/COMMIT_EDITMSG" - -# Check if the commit message file exists -if [ -e "$commit_msg_file" ]; then - commit_message=$(cat "$commit_msg_file") - - # Use $commit_message as needed - echo "Commit message: $commit_message" - - # Your logic here, for example, running check-for-issue-reference - node ./check-for-issue-reference "$commit_message" || { - echo "husky: commit-msg hook failed (add --no-verify to bypass)" && exit 1 - } - - npx commitlint --edit "$commit_msg_file" -else - echo "Error: Commit message file not found: $commit_msg_file" - exit 1 -fi - -npx --no -- commitlint --edit "$1" diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100644 index 605953f..0000000 --- a/.husky/pre-commit +++ /dev/null @@ -1 +0,0 @@ -. "$(dirname -- "$0")/_/husky.sh" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ffd9a14 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +ARG BACKEND_URL=http://127.0.0.1:5174 + +FROM node:20-bullseye + +RUN apt-get update && apt-get install -y vim + +RUN npm install -g pnpm serve + +# Set the working directory +WORKDIR /app +COPY . /app + +ARG BACKEND_URL +ENV VITE_BACKEND_URL=$BACKEND_URL +RUN echo "The backend URL is $BACKEND_URL" +RUN mkdir /app/temp + +RUN pnpm install +RUN pnpm build:all diff --git a/backend/package.json b/backend/package.json index 147a14d..0ec893a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,7 +5,8 @@ "main": "index.ts", "scripts": { "dev": "concurrently -k \"tsc -w\" \"nodemon --env-file=.env.local ./dist/index.js\"", - "build": "tsc" + "build": "tsc", + "run": "node ./dist/index.js" }, "type": "module", "keywords": [], diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..61010b0 --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,81 @@ +services: + # application service + backend: + image: ghcr.io/golemfactory/deposit_example:${DEPLOY_BRANCH:-latest} + command: pnpm run run + working_dir: /app/backend + environment: + - YAGNA_APPKEY=66667777888 + - YAGNA_API_URL=http://yagna:7465 + - JWT_SECRET=dup]a + - JWT_TOKEN_EXPIRATION=1d + - JWT_REFRESH_TOKEN_EXPIRATION=7d + - JWT_ISSUER=golem.network + - MONGO_URI=mongodb://${MONGO_ROOT_USER}:${MONGO_ROOT_PASSWORD}@mongo:27017/ + - HOST=0.0.0.0 + - PORT=5174 + - DB_NAME=depositDB + - DEPOSIT_CONTRACT_ADDRESS=0xb9919c8D8D384d93C195503064A3b303Ea8Fdbaa + ports: + - "5174:5174" + depends_on: + - yagna + - mongo + + frontend: + image: ghcr.io/golemfactory/deposit_example:${DEPLOY_BRANCH:-latest} + command: pnpm run run + working_dir: /app/frontend + environment: + - YAGNA_APPKEY=66667777888 + - YAGNA_API_URL=http://yagna:7465 + - JWT_SECRET=dup]a + - JWT_TOKEN_EXPIRATION=1d + - JWT_REFRESH_TOKEN_EXPIRATION=7d + - JWT_ISSUER=golem.network + - MONGO_URI=mongodb://${MONGO_ROOT_USER}:${MONGO_ROOT_PASSWORD}@mongo:27017/ + - HOST=0.0.0.0 + - PORT=5174 + - DB_NAME=depositDB + - DEPOSIT_CONTRACT_ADDRESS=0xb9919c8D8D384d93C195503064A3b303Ea8Fdbaa + ports: + - "3000:3000" + depends_on: + - backend + # yagna service + yagna: + build: + context: ../yagna + dockerfile: Dockerfile + args: + - YAGNA_VERSION=pre-rel-v0.15.0-deposits-beta1 + command: yagna service run + environment: + - YAGNA_AUTOCONF_APPKEY=66667777888 + - YAGNA_AUTOCONF_ID_SECRET=0000000000000000000000000000000000000000000000000000000222222222 + - YAGNA_API_URL=http://0.0.0.0:7465 + - SUBNET=change_me + - YA_NET_BIND_URL=udp://0.0.0.0:0 + # mongo service + mongo: + image: mongo + environment: + - MONGO_INITDB_ROOT_USERNAME=${MONGO_ROOT_USER} + - MONGO_INITDB_ROOT_PASSWORD=${MONGO_ROOT_PASSWORD} + - MONGO_INITDB_DATABASE=project + # mongo express service + mongo-express: + image: mongo-express + environment: + - ME_CONFIG_MONGODB_SERVER=mongo + - ME_CONFIG_MONGODB_PORT=27017 + - ME_CONFIG_MONGODB_ENABLE_ADMIN=false + - ME_CONFIG_MONGODB_AUTH_DATABASE=admin + - ME_CONFIG_MONGODB_AUTH_USERNAME=${MONGO_ROOT_USER} + - ME_CONFIG_MONGODB_AUTH_PASSWORD=${MONGO_ROOT_PASSWORD} + - ME_CONFIG_BASICAUTH_USERNAME=${MONGOEXPRESS_LOGIN} + - ME_CONFIG_BASICAUTH_PASSWORD=${MONGOEXPRESS_PASSWORD} + depends_on: + - mongo + ports: + - "8888:8081" \ No newline at end of file diff --git a/deploy/npm_server.js b/deploy/npm_server.js new file mode 100644 index 0000000..d077eb8 --- /dev/null +++ b/deploy/npm_server.js @@ -0,0 +1,18 @@ +const express = require('express'); +const { spawn } = require('child_process'); + +const app = express(); + +app.get('/release/pull', (req, res) => { + const deployProcess = spawn('/bin/bash', ['-c', './script.sh'], + { + cwd: process.cwd(), + stdio: "inherit" + } + ); + res.send('Hello World'); +}); + +const server = app.listen(5000, '0.0.0.0', () => { + console.log('Server running'); +}); diff --git a/deploy/package.json b/deploy/package.json new file mode 100644 index 0000000..7afc1b9 --- /dev/null +++ b/deploy/package.json @@ -0,0 +1,10 @@ +{ + "name": "deposit-payments-deploy-updater", + "version": "1.0.0", + "dependencies": { + "express": "^4.17.1" + }, + "scripts": { + "start": "node npm_server.js" + } +} \ No newline at end of file diff --git a/deploy/script.sh b/deploy/script.sh new file mode 100755 index 0000000..8f70159 --- /dev/null +++ b/deploy/script.sh @@ -0,0 +1,7 @@ +for i in {1..10} +do + docker-compose pull + # docker-compose config + docker-compose up -d + sleep 10 +done diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml new file mode 100644 index 0000000..ba48542 --- /dev/null +++ b/docker-compose-dev.yml @@ -0,0 +1,61 @@ +services: + # application service + app: + build: + context: . + dockerfile: Dockerfile + args: + - BACKEND_URL=${BACKEND_URL:-http://127.0.0.1:5174} + command: tail -F anything + environment: + - YAGNA_APPKEY=66667777888 + - YAGNA_API_URL=http://yagna:7465 + - JWT_SECRET=dup]a + - JWT_TOKEN_EXPIRATION=1d + - JWT_REFRESH_TOKEN_EXPIRATION=7d + - JWT_ISSUER=golem.network + - MONGO_URI=mongodb://${MONGO_ROOT_USER}:${MONGO_ROOT_PASSWORD}@mongo:27017/ + - HOST=0.0.0.0 + - PORT=5174 + - DB_NAME=depositDB + - DEPOSIT_CONTRACT_ADDRESS=0xb9919c8D8D384d93C195503064A3b303Ea8Fdbaa + ports: + - "3000:3000" + - "5174:5174" + # yagna service + yagna: + build: + context: ./yagna + dockerfile: Dockerfile + args: + - YAGNA_VERSION=pre-rel-v0.15.0-deposits-beta1 + command: yagna service run + environment: + - YAGNA_AUTOCONF_APPKEY=66667777888 + - YAGNA_AUTOCONF_ID_SECRET=0000000000000000000000000000000000000000000000000000000222222222 + - YAGNA_API_URL=http://0.0.0.0:7465 + - SUBNET=change_me + - YA_NET_BIND_URL=udp://0.0.0.0:0 + # mongo service + mongo: + image: mongo + environment: + - MONGO_INITDB_ROOT_USERNAME=${MONGO_ROOT_USER} + - MONGO_INITDB_ROOT_PASSWORD=${MONGO_ROOT_PASSWORD} + - MONGO_INITDB_DATABASE=project + # mongo express service + mongo-express: + image: mongo-express + environment: + - ME_CONFIG_MONGODB_SERVER=mongo + - ME_CONFIG_MONGODB_PORT=27017 + - ME_CONFIG_MONGODB_ENABLE_ADMIN=false + - ME_CONFIG_MONGODB_AUTH_DATABASE=admin + - ME_CONFIG_MONGODB_AUTH_USERNAME=${MONGO_ROOT_USER} + - ME_CONFIG_MONGODB_AUTH_PASSWORD=${MONGO_ROOT_PASSWORD} + - ME_CONFIG_BASICAUTH_USERNAME=${MONGOEXPRESS_LOGIN} + - ME_CONFIG_BASICAUTH_PASSWORD=${MONGOEXPRESS_PASSWORD} + depends_on: + - mongo + ports: + - "8888:8081" \ No newline at end of file diff --git a/frontend/package.json b/frontend/package.json index 170a67b..a87f506 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,6 +5,7 @@ "scripts": { "dev": "vite", "build": "tsc && vite build", + "run": "serve dist -l tcp://0.0.0.0:3000", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, diff --git a/loginWithCrypto/package.json b/loginWithCrypto/package.json index 57f51ab..dadcbab 100644 --- a/loginWithCrypto/package.json +++ b/loginWithCrypto/package.json @@ -8,10 +8,10 @@ "test": "jest", "build": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:types", "build:watch": "pnpm run build:cjs:watch & pnpm run build:esm:watch & pnpm run build:types:watch", - "build:cjs": "tsc --module commonjs --outDir ./dist/_cjs --removeComments --verbatimModuleSyntax false --skipLibCheck && echo {\"type\":\"commonjs\"} > ./dist/_cjs/package.json", - "build:cjs:watch": "tsc --watch --module commonjs --outDir ./dist/_cjs --removeComments --verbatimModuleSyntax false --skipLibCheck && echo {\"type\":\"commonjs\"} > ./dist/_cjs/package.json", - "build:esm": "tsc --module es2015 --outDir ./dist/_esm --skipLibCheck && echo {\"type\": \"module\",\"sideEffects\":false} > ./dist/_esm/package.json", - "build:esm:watch": "tsc --watch --module es2015 --outDir ./dist/_esm --skipLibCheck && echo {\"type\": \"module\",\"sideEffects\":false} > ./dist/_esm/package.json", + "build:cjs": "tsc --module commonjs --outDir ./dist/_cjs --removeComments --verbatimModuleSyntax false --skipLibCheck && echo {\\\"type\\\":\\\"commonjs\\\"} > ./dist/_cjs/package.json", + "build:cjs:watch": "tsc --watch --module commonjs --outDir ./dist/_cjs --removeComments --verbatimModuleSyntax false --skipLibCheck && echo {\\\"type\\\":\\\"commonjs\\\"} > ./dist/_cjs/package.json", + "build:esm": "tsc --module es2015 --outDir ./dist/_esm --skipLibCheck && echo {\\\"type\\\": \\\"module\\\",\\\"sideEffects\\\":false} > ./dist/_esm/package.json", + "build:esm:watch": "tsc --watch --module es2015 --outDir ./dist/_esm --skipLibCheck && echo {\\\"type\\\": \\\"module\\\",\\\"sideEffects\\\":false} > ./dist/_esm/package.json", "build:types": "tsc --declarationDir ./dist/_types --emitDeclarationOnly --declaration --declarationMap --skipLibCheck ", "build:types:watch": "tsc --watch --declarationDir ./dist/_types --emitDeclarationOnly --declaration --declarationMap --skipLibCheck " }, diff --git a/package.json b/package.json index 2b2f866..a244ecb 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "build:ya-ts-client": "pnpm --filter ya-ts-client build", "build:loginWithCrypto": "pnpm --filter loginWithCrypto build", "build:backend": "pnpm --filter backend build", - "build:all": "pnpm build:loginWithCrypto && pnpm build:ya-ts-client && pnpm build:golem-js && pnpm build:task-executor && pnpm build:backend" + "build:frontend": "pnpm --filter deposit:frontend build", + "build:all": "pnpm build:loginWithCrypto && pnpm build:ya-ts-client && pnpm build:golem-js && pnpm build:task-executor && pnpm build:backend && pnpm build:frontend" }, "keywords": [], "author": "", diff --git a/yagna/Dockerfile b/yagna/Dockerfile new file mode 100644 index 0000000..1676e44 --- /dev/null +++ b/yagna/Dockerfile @@ -0,0 +1,25 @@ +# Full python toolset for ease of development +# If you need something smaller, you can use ubuntu slim or alpine without python +FROM python:latest + +# This tools are not needed but are helpful for debugging +RUN apt-get update -y +RUN apt-get install -y build-essential net-tools iputils-ping curl vim git wget unzip jq dnsutils tcpdump +RUN pip install --upgrade pip + +# Download official installer +RUN curl -L https://join.golem.network/as-requestor --output as-requestor.sh +RUN chmod +x as-requestor.sh + +# Installer is checking if binaries in in this PATH, so we need to add it beforehand +ENV PATH="${PATH}:/root/.local/bin" + +# switch to any yagna version if necessery +ARG YAGNA_VERSION + +# yagna installator normally asks for user input, so we need to set some environment variables to avoid that +RUN GOLEM_ACCEPT_TOS=yes BATCH_MODE=yes YA_INSTALLER_CORE=${YAGNA_VERSION} ./as-requestor.sh + + + +