diff --git a/.github/actions/build-rpch/action.yml b/.github/actions/build-rpch/action.yml deleted file mode 100644 index a49b3abe7..000000000 --- a/.github/actions/build-rpch/action.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: "Build RPCh monorepo" -description: "Build the RPCh monorepo" - -runs: - using: "composite" - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@v1.2.0 - with: - large-packages: false - - name: Setup Node.js environment - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: "yarn" - cache-dependency-path: ./yarn.lock - registry-url: "https://registry.npmjs.org/" - - - name: Install dependencies - shell: bash - run: yarn - - - name: Build - shell: bash - run: yarn build diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..d725786a7 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,26 @@ +# GitHub Workflows + +This document describes the GitHub workflows used in this project. + +## Build + +- Builds, Lint, Test +- Publishes the docker images with version `x.y.z-pr.` +- If the PR has attached the label `deploy_staging` it will update the docker images `staging` and will deploy the version in the staging environment + +## Merge PR + +- Publishes the docker image with `latest` +- Publishes the docker image with `staging` +- Deploy the tag `staging` in the staging environment + +## Close release + +This is a workflow triggered manually from Github Actions [Close Release](https://github.com/hoprnet/RPCh/actions/workflows/release.yaml). The tasks performed by this workflow include: + +- Publishes the docker image with `x.y.z` +- Create a Github release +- Tag code +- Changelog is autogenerated by commit linear history of the release +- Bumps the new version +- Sends a Zulip notification diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 000000000..a53c70542 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,123 @@ +--- +name: Build + +on: + pull_request: + types: + - opened + - synchronize + - reopened + - labeled + +concurrency: + group: build + cancel-in-progress: true + +jobs: + build: + name: Build + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [18.x, 20.x, 22.x] + + services: + # required by unit tests + postgres: + image: postgres + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + # set health checks to wait until postgres has started + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: hoprnet/hopr-workflows/actions/setup-node-js@master + with: + node-version: ${{ matrix.node-version }} + + - name: Building + run: yarn build + + - name: Linting + run: yarn lint:ci + + - name: Formatting + run: yarn format:ci + + - name: Review dependencies + # TODO: update ethers to v6 in RPCh SDK to remove the ignore-path + run: yarn depcheck --ignore-path="examples" + + - name: Testing + run: yarn test + env: + DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres + + # - name: Run E2E tests + # run: yarn test:e2e + + publish: + name: Publish + runs-on: self-hosted-hoprnet-small + needs: build + strategy: + matrix: + project: + - discovery-platform + - rpc-server + - availability-monitor + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup GCP + id: gcp + uses: hoprnet/hopr-workflows/actions/setup-gcp@master + with: + google-credentials: ${{ secrets.GOOGLE_HOPRASSOCIATION_CREDENTIALS_REGISTRY }} + login-artifact-registry: 'true' + install-sdk: 'true' + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver: kubernetes + + - name: Get PR version + id: variables + run: | + PR_VERSION=$(jq -r '.version' apps/"${{ matrix.project }}"/package.json)-pr."${{ github.event.pull_request.number }}" + echo "PR_VERSION=${PR_VERSION}" >> $GITHUB_OUTPUT + + - name: Build and push docker image + uses: docker/build-push-action@v6 + with: + push: true + file: "./apps/${{ matrix.project }}/Dockerfile" + tags: ${{ vars.DOCKER_IMAGE_REGISTRY }}/${{ matrix.project }}:${{ steps.variables.outputs.PR_VERSION }} + + - name: Tag staging + if: contains(github.event.pull_request.labels.*.name, 'deploy_staging') || github.event.label.name == 'deploy_staging' && github.event.action == 'labeled' + run: | + gcloud artifacts docker tags add ${{ vars.DOCKER_IMAGE_REGISTRY }}/${{ matrix.project }}:${{ steps.variables.outputs.PR_VERSION }} ${{ vars.DOCKER_IMAGE_REGISTRY }}/${{ matrix.project }}:staging + + deploy: + name: Deploy + needs: publish + if: contains(github.event.pull_request.labels.*.name, 'deploy_staging') || github.event.label.name == 'deploy_staging' && github.event.action == 'labeled' + uses: ./.github/workflows/deploy.yaml + with: + branch: ${{ github.event.pull_request.head.ref }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 000000000..d96100c81 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,38 @@ +--- +name: Deploy + +on: + workflow_call: + inputs: + branch: + required: true + type: string + +concurrency: + group: deploy + cancel-in-progress: true + +jobs: + + deploy: + name: Deploy staging + runs-on: self-hosted-hoprnet-small + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ inputs.branch }} + + - name: Setup GCP + id: gcp + uses: hoprnet/hopr-workflows/actions/setup-gcp@master + with: + google-credentials: ${{ secrets.GCP_SA_TERRAFORM_JSON_STAGING }} + project: hopr-staging + login-gke: 'true' + + - name: "Restart deployment" + run: | + echo "[INFO] Restarting degen deployment" + kubectl rollout restart deployments -n uhttp availability-monitor discovery-platform + kubectl rollout status -w deployments -n uhttp availability-monitor discovery-platform \ No newline at end of file diff --git a/.github/workflows/merge.yaml b/.github/workflows/merge.yaml new file mode 100644 index 000000000..a2ddc4786 --- /dev/null +++ b/.github/workflows/merge.yaml @@ -0,0 +1,57 @@ +name: Merge PR + +on: + pull_request: + types: + - closed + branches: + - main + +concurrency: + group: merge + cancel-in-progress: false + +jobs: + merge: + name: Merge PR + runs-on: self-hosted-hoprnet-small + if: github.event.pull_request.merged == true + strategy: + matrix: + project: + - discovery-platform + - rpc-server + - availability-monitor + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup GCP + id: gcp + uses: hoprnet/hopr-workflows/actions/setup-gcp@master + with: + google-credentials: ${{ secrets.GOOGLE_HOPRASSOCIATION_CREDENTIALS_REGISTRY }} + login-artifact-registry: 'true' + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver: kubernetes + + - name: Build and push docker image + uses: docker/build-push-action@v6 + with: + push: true + file: "./apps/${{ matrix.project }}/Dockerfile" + tags: | + ${{ vars.DOCKER_IMAGE_REGISTRY }}/${{ matrix.project }}:staging + ${{ vars.DOCKER_IMAGE_REGISTRY }}/${{ matrix.project }}:latest + + deploy: + name: Deploy staging + needs: merge + uses: ./.github/workflows/deploy.yaml + with: + branch: ${{ github.event.pull_request.head.ref }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 000000000..17ebed993 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,110 @@ +name: Close release + +on: + workflow_dispatch: + inputs: + release_type: + description: 'Next version type' + required: true + type: choice + default: 'patch' + options: + - patch + - minor + - major + project: + description: 'Project' + required: true + type: choice + options: + - discovery-platform + - rpc-server + - availability-monitor + +concurrency: + group: release + cancel-in-progress: false + +jobs: + release: + name: Close release + runs-on: self-hosted-hoprnet-small + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: hoprnet/hopr-workflows/actions/setup-node-js@master + with: + node-version: ${{ vars.NODE_VERSION }} + + - name: Setup GCP + id: gcp + uses: hoprnet/hopr-workflows/actions/setup-gcp@master + with: + google-credentials: ${{ secrets.GOOGLE_HOPRASSOCIATION_CREDENTIALS_REGISTRY }} + login-artifact-registry: 'true' + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver: kubernetes + + - name: Building + run: yarn build + + - name: Linting + run: yarn lint:ci + + - name: Formatting + run: yarn format:ci + + - name: Testing + run: yarn test + + - name: Setup environment variables + id: environment + run: | + PACKAGE_VERSION=$(jq -r '.version' "apps/${{ inputs.project }}/package.json") + echo "release_version=${PACKAGE_VERSION}" >> $GITHUB_OUTPUT + + - name: Create Release + uses: softprops/action-gh-release@v2 + with: + name: '${{ inputs.project }} - v${{ steps.environment.outputs.release_version }}' + tag_name: v${{ steps.environment.outputs.release_version }} + + - name: Build and push docker image + uses: docker/build-push-action@v6 + with: + push: true + file: "./apps/${{ inputs.project }}/Dockerfile" + tags: ${{ vars.DOCKER_IMAGE_REGISTRY }}/${{ inputs.project }}:${{ steps.environment.outputs.release_version }} + + - name: Bump Version + id: bump + run: | + npm version ${{ inputs.release_type }} -w "apps/${{ inputs.project }}" --no-git-tag-version + BUMP_VERSION=$(jq -r '.version' "apps/${{ inputs.project }}/package.json") + echo "bump_version=${BUMP_VERSION}" >> $GITHUB_OUTPUT + + - uses: EndBug/add-and-commit@v9 + with: + add: 'apps/${{ inputs.project}}' + default_author: github_actor + new_branch: main + message: 'Bump ${{ inputs.project }} version to ${{ steps.bump.outputs.bump_version }}' + pathspec_error_handling: exitImmediately + + - name: Notify new release + uses: zulip/github-actions-zulip/send-message@v1 + with: + api-key: ${{ secrets.ZULIP_API_KEY }} + email: ${{ secrets.ZULIP_EMAIL }} + organization-url: 'https://hopr.zulipchat.com' + type: 'stream' + to: 'Releases' + topic: 'main' + content: | + I'm thrilled to inform the new **${{ vars.DOCKER_IMAGE_NAME }}** version **${{ steps.environment.outputs.release_version }}** has been released. diff --git a/.github/workflows/review.yml b/.github/workflows/review.yml deleted file mode 100644 index a88073102..000000000 --- a/.github/workflows/review.yml +++ /dev/null @@ -1,213 +0,0 @@ -name: Review - -on: - push: - branches: [main] - tags: - - '**' - pull_request: - types: [opened, synchronize] - -concurrency: - # find the branch name for 'pull_request' or on 'push' events - group: ${{ github.head_ref || github.ref_name }} - cancel-in-progress: true - -jobs: - review-source-code: - name: Review source code - timeout-minutes: 10 - runs-on: ubuntu-latest - env: - # enable remote caching using turbo - TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} - TURBO_TEAM: ${{ secrets.TURBO_TEAM }} - - services: - # required by unit tests - postgres: - image: postgres - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - # set health checks to wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Build - uses: ./.github/actions/build-rpch - env: - TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} - TURBO_TEAM: ${{ secrets.TURBO_TEAM }} - - - name: Review linting - run: yarn lint:ci - - - name: Review formatting - run: yarn format:ci - - - name: Review dependencies - # TODO: update ethers to v6 in RPCh SDK to remove the ignore-path - run: yarn depcheck --ignore-path="examples" - - - name: Run tests and coverage - run: yarn test - env: - DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres - - container-image: - name: Build and push container image - timeout-minutes: 10 - runs-on: ubuntu-latest - strategy: - matrix: - # TODO: dynamically get this list - project: - - discovery-platform - - rpc-server - - availability-monitor - include: - - project: discovery-platform - directory: apps - - project: availability-monitor - directory: apps - - project: rpc-server - directory: apps - - steps: - - name: Check out code - uses: actions/checkout@v4 - - - name: Get docker tag - id: docker-tag - run: | - main_version=$(jq -r '.version' apps/${{ matrix.project }}/package.json) - pr_number=${{ github.event.pull_request.number }} - if [ ! -z "$pr_number" ]; then - commit_short_sha=$(git rev-parse --short "${COMMIT_SHA:-HEAD}") - docker_tag="${main_version}-pr.${pr_number}-commit.${commit_short_sha}" - echo "DOCKER_TAG=${docker_tag}" >> $GITHUB_OUTPUT - else - echo "DOCKER_TAG=${main_version}" >> $GITHUB_OUTPUT - fi - env: - COMMIT_SHA: ${{ github.event.pull_request.head.sha }} - - - name: Set up Google Cloud Credentials - id: auth - uses: google-github-actions/auth@v2 - with: - token_format: "access_token" - credentials_json: ${{ secrets.GOOGLE_HOPRASSOCIATION_CREDENTIALS_REGISTRY }} - - - name: Set up Google Cloud SDK - uses: google-github-actions/setup-gcloud@v2 - with: - project_id: hoprassociation - install_components: beta - - - name: Login Google Container Registry - uses: docker/login-action@v3 - with: - registry: europe-west3-docker.pkg.dev - username: oauth2accesstoken - password: ${{ steps.auth.outputs.access_token }} - - - name: Build container image - uses: docker/build-push-action@v5 - with: - push: true - file: "./${{ matrix.directory }}/${{ matrix.project }}/Dockerfile" - tags: | - europe-west3-docker.pkg.dev/hoprassociation/docker-images/${{ matrix.project }}:${{ steps.docker-tag.outputs.DOCKER_TAG }} - - review-configuration: - name: Review configuration - timeout-minutes: 10 - runs-on: ubuntu-latest - - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Review licenses - run: > - find . -name 'package.json' -not -path "*/node_modules/*" \ - -exec jq --arg license 'LGPL-3.0' -r '.license == $license' {} +\ - | grep "false" && exit 1 || echo success - - review-e2e-test-results: - needs: - - review-source-code - - container-image - - review-configuration - name: Review E2E test results - timeout-minutes: 60 - runs-on: ubuntu-latest - env: - # enable remote caching using turbo - TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} - TURBO_TEAM: ${{ secrets.TURBO_TEAM }} - - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Build - uses: ./.github/actions/build-rpch - env: - TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} - TURBO_TEAM: ${{ secrets.TURBO_TEAM }} - - - name: Run E2E tests - run: yarn test:e2e - - # uncomment changeset publish is fixed https://github.com/changesets/changesets/issues/942 - # publish jobs require to be under branches release/** - # publish-npm-packages: - # if: startsWith(github.head_ref, 'release/') - # needs: - # - review-source-code - # - review-dockerfiles - # - review-configuration - # - review-e2e-test-results - # name: Publish NPM packages - # timeout-minutes: 10 - # runs-on: ubuntu-latest - # env: - # # enable remote caching using turbo - # TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} - # TURBO_TEAM: ${{ secrets.TURBO_TEAM }} - - # steps: - # - name: Check out code - # uses: actions/checkout@v3 - - # - name: Build - # uses: ./.github/actions/build-rpch - # env: - # TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} - # TURBO_TEAM: ${{ secrets.TURBO_TEAM }} - - # - name: Creating .npmrc - # run: | - # cat << EOF > "$HOME/.npmrc" - # //registry.npmjs.org/:_authToken=$NPM_TOKEN - # EOF - # env: - # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - # - name: Publish - # run: npx changeset publish - # env: - # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 2040653e8..e20902502 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,6 @@ exit-node.sqlite #k6 results devkit/loadtesting-k6/results/* + +# Created by github pipeline +gha-creds-*.json \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..596eab45d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +# Created by github pipeline +gha-creds-*.json \ No newline at end of file diff --git a/README.md b/README.md index a0e8d2e55..669eb3bca 100644 --- a/README.md +++ b/README.md @@ -60,19 +60,13 @@ v # single letter 'v' X.X.X # Semver versioning for that app or package ``` -## Deployment +## Deployment process -Github Workflows builds and pushes container images to our configured artifacts registry. -During development changesets are used to manage user facing changelogs. +To contribute to this repository you will need to create a pull request. More information about the existing automated workflows can be found in [GitHub Actions](./.github/workflows/README.md) ### Staging deployment -To update singular applications on staging, the usual flow is like this: - -- Create PR with desired changes -- Wait for automation job to build and upload container -- Take container hash - easiest from [artifacts registry](https://console.cloud.google.com/artifacts/docker/hoprassociation/europe-west3/docker-images?project=hoprassociation&supportedpurview=project) -- Use hash according to deployment instructions for the desired applications further down +To deploy availability-monitor and discovery-platform on staging, tag the PR with the label `deploy_staging` ### Production deployment @@ -85,20 +79,6 @@ To update singular applications on staging, the usual flow is like this: - Push it `$ git push origin main --tags` - After the correct tags for your application where built, follow deployment instructions further down -### Availability Monitor - -Version tag on main branch: `@rpch/availability-monitor-vX.X.X` - -The Availability Monitor is managed via [applications](https://github.com/Rpc-h/applications) repo. -Update version in `/availability-monitor/application.yaml` and push to main branch. - -### Discovery Platform - -Version tag on main branch: `@rpch/discovery-platform-vX.X.X` - -The Discovery Platform is managed via [applications](https://github.com/Rpc-h/applications) repo. -Update version in `/discovery-platform/application.yaml` and push to main branch. - ### RPC Server Version tag on main branch: `@rpch/rpc-server-vX.X.X` diff --git a/examples/ethers/src/index.ts b/examples/ethers/src/index.ts index 2a5832ca2..74b1b399b 100644 --- a/examples/ethers/src/index.ts +++ b/examples/ethers/src/index.ts @@ -8,7 +8,10 @@ dotenv.config(); * so they can send their RPC requests through the RPCh network. */ export class RPChProvider extends JsonRpcProvider { - constructor(public readonly url: string, public readonly sdk: SDK) { + constructor( + public readonly url: string, + public readonly sdk: SDK, + ) { super(url); } diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 3ba4308cc..ed5a5ca53 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -94,7 +94,10 @@ export default class SDK { * @param crypto crypto instantiation for RPCh, use `@rpch/crypto-for-nodejs` or `@rpch/crypto-for-web` * @param ops, see **Ops** **/ - constructor(private readonly clientId: string, ops: Ops = {}) { + constructor( + private readonly clientId: string, + ops: Ops = {}, + ) { this.ops = this.sdkOps(ops); (this.ops.debugScope || this.ops.logLevel) && Utils.setDebugScopeLevel(this.ops.debugScope, this.ops.logLevel);