From 6ead00a04ef442166dab32df00e4c7f8676a3ae9 Mon Sep 17 00:00:00 2001 From: Rafael Belchior Date: Tue, 18 Feb 2025 17:32:02 +0200 Subject: [PATCH] ci(satp-hermes): add docker image deployment actions --- .github/workflows/ci.yaml | 64 --------- .github/workflows/satp-hermes-gateway.yaml | 127 ++++++++++++++++++ packages/cactus-plugin-satp-hermes/README.md | 14 ++ .../generated/SATPWrapperContract.ts | 110 +++++++-------- .../integration/gateway-init-startup.test.ts | 5 +- ...e-transfer-1-gateway-dockerization.test.ts | 2 +- ...-transfer-2-gateways-dockerization.test.ts | 2 +- 7 files changed, 201 insertions(+), 123 deletions(-) create mode 100644 .github/workflows/satp-hermes-gateway.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 51e64871ca..e7717e0ec7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1759,71 +1759,7 @@ jobs: with: name: coverage-reports-35 path: ./code-coverage-ts/**/ - cactus-plugin-satp-hermes: - continue-on-error: false - env: - FULL_BUILD_DISABLED: true - JEST_TEST_PATTERN: packages/cactus-plugin-satp-hermes/src/test/typescript/(unit|integration|benchmark)/.*/*.test.ts - JEST_TEST_RUNNER_DISABLED: false - TAPE_TEST_RUNNER_DISABLED: true - needs: build-dev - runs-on: ubuntu-22.04 - steps: - - name: Use Node.js ${{ env.NODEJS_VERSION }} - uses: actions/setup-node@v4.0.2 - with: - node-version: ${{ env.NODEJS_VERSION }} - - uses: actions/checkout@v4.1.1 - - id: yarn-cache-dir-path - name: Get yarn cache directory path - run: echo "dir=$(yarn cache dir)" >> "$GITHUB_OUTPUT" - - id: yarn-cache - name: Restore Yarn Cache - uses: actions/cache@v4.0.1 - with: - key: ${{ runner.os }}-yarn-${{ hashFiles('./yarn.lock') }} - path: ./.yarn/ - restore-keys: | - ${{ runner.os }}-yarn- - - run: ./tools/ci.sh cp-bungee-hermes: - continue-on-error: false - env: - # Otherwise it fails with: You are running out of disk space. - # The runner will stop working when the machine runs out of disk space. - # Free space left: 26 MB - FREE_UP_GITHUB_RUNNER_DISK_SPACE_DISABLED: false - FULL_BUILD_DISABLED: true - JEST_TEST_PATTERN: packages/cactus-plugin-satp-hermes/src/test/typescript/(unit|integration|benchmark)/.*/*.test.ts - JEST_TEST_RUNNER_DISABLED: false - JEST_TEST_COVERAGE_PATH: ./code-coverage-ts/cp-bungee-hermes - JEST_TEST_CODE_COVERAGE_ENABLED: true - TAPE_TEST_RUNNER_DISABLED: true - needs: build-dev - runs-on: ubuntu-22.04 - steps: - - name: Use Node.js ${{ env.NODEJS_VERSION }} - uses: actions/setup-node@v4.0.3 - with: - node-version: ${{ env.NODEJS_VERSION }} - - uses: actions/checkout@v4.1.7 - - - id: yarn-cache - name: Restore Yarn Cache - uses: actions/cache@v4.0.2 - with: - key: ${{ runner.os }}-yarn-${{ hashFiles('./yarn.lock') }} - path: ./.yarn/ - restore-keys: | - ${{ runner.os }}-yarn- - - run: ./tools/ci.sh - if: ${{ env.RUN_CODE_COVERAGE == 'true' }} - - name: Upload coverage reports as artifacts - uses: actions/upload-artifact@v4.3.3 - with: - name: coverage-reports-36 - path: ./code-coverage-ts/**/ - cactus-plugin-bungee-hermes: continue-on-error: false env: FULL_BUILD_DISABLED: true diff --git a/.github/workflows/satp-hermes-gateway.yaml b/.github/workflows/satp-hermes-gateway.yaml new file mode 100644 index 0000000000..5aca2af7fe --- /dev/null +++ b/.github/workflows/satp-hermes-gateway.yaml @@ -0,0 +1,127 @@ +name: SATP CI - tests and docker deployments +on: + pull_request: + branches: [main, dev] + push: + branches: [main, dev] + +jobs: + run-satp-tests: + continue-on-error: false + env: + FULL_BUILD_DISABLED: true + JEST_TEST_PATTERN: packages/cactus-plugin-satp-hermes/src/test/typescript/(unit|integration|benchmark)/.*/*.test.ts + JEST_TEST_RUNNER_DISABLED: false + TAPE_TEST_RUNNER_DISABLED: true + needs: build-dev + runs-on: ubuntu-22.04 + steps: + - name: Use Node.js ${{ env.NODEJS_VERSION }} + uses: actions/setup-node@v4.0.2 + with: + node-version: ${{ env.NODEJS_VERSION }} + - uses: actions/checkout@v4.1.1 + - id: yarn-cache-dir-path + name: Get yarn cache directory path + run: echo "dir=$(yarn cache dir)" >> "$GITHUB_OUTPUT" + - id: yarn-cache + name: Restore Yarn Cache + uses: actions/cache@v4.0.1 + with: + key: ${{ runner.os }}-yarn-${{ hashFiles('./yarn.lock') }} + path: ./.yarn/ + restore-keys: | + ${{ runner.os }}-yarn- + - run: ./tools/ci.sh + + set-docker-tags: + runs-on: ubuntu-22.04 + needs: run-satp-tests + if: github.event_name == 'push' + outputs: + tag_suffix: ${{ steps.set_tags.outputs.tag_suffix }} + tag_version: ${{ steps.set_tags.outputs.tag_version }} + dockerhub_image: ${{ steps.set_tags.outputs.dockerhub_image }} + ghcr_image: ${{ steps.set_tags.outputs.ghcr_image }} + steps: + - uses: actions/checkout@v4.1.7 + - name: Set image tags + id: set_tags + run: | + TAG_SUFFIX=$(if [ "${{ github.ref }}" = "refs/heads/main" ]; then echo "prod"; else echo "dev"; fi) + TAG_VERSION="$(date -u +"%Y-%m-%dT%H-%M-%S")-${TAG_SUFFIX}-$(git rev-parse --short HEAD)" + DOCKERHUB_IMAGE="hyperledger/satp-hermes-gateway" + GHCR_IMAGE="ghcr.io/hyperledger-cacti/satp-hermes-gateway" + echo "tag_suffix=${TAG_SUFFIX}" >> $GITHUB_OUTPUT + echo "tag_version=${TAG_VERSION}" >> $GITHUB_OUTPUT + echo "dockerhub_image=${DOCKERHUB_IMAGE}" >> $GITHUB_OUTPUT + echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT + + build-and-push-dockerhub: + runs-on: ubuntu-22.04 + needs: set-docker-tags + if: github.event_name == 'push' + steps: + - uses: actions/checkout@v4.1.7 + - name: Configure and build bundle + run: | + yarn configure + yarn lerna run build:bundle --scope=@hyperledger/cactus-plugin-satp-hermes + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PAT }} + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: ./packages/cactus-plugin-satp-hermes/ + file: ./packages/cactus-plugin-satp-hermes/satp-hermes-gateway.Dockerfile + push: true + labels: | + org.opencontainers.image.source=https://github.com/hyperledger/cacti + org.opencontainers.image.description=SATP Hermes Gateway + org.opencontainers.image.licenses=Apache-2.0 + org.opencontainers.image.vendor=Hyperledger + org.opencontainers.image.version=${{ needs.set-docker-tags.outputs.tag_version }} + org.opencontainers.image.visibility=public + tags: | + ${{ needs.set-docker-tags.outputs.dockerhub_image }}:${{ needs.set-docker-tags.outputs.tag_version }} + ${{ needs.set-docker-tags.outputs.dockerhub_image }}:latest + + build-and-push-ghcr: + runs-on: ubuntu-22.04 + needs: set-docker-tags + if: github.event_name == 'push' + steps: + - uses: actions/checkout@v4.1.7 + - name: Configure and build bundle + run: | + yarn configure + yarn lerna run build:bundle --scope=@hyperledger/cactus-plugin-satp-hermes + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ secrets.GHCR_USERNAME }} + password: ${{ secrets.GHCR_TOKEN }} + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: ./packages/cactus-plugin-satp-hermes/ + file: ./packages/cactus-plugin-satp-hermes/satp-hermes-gateway.Dockerfile + push: true + labels: | + org.opencontainers.image.source=https://github.com/hyperledger/cacti + org.opencontainers.image.description=SATP Hermes Gateway + org.opencontainers.image.licenses=Apache-2.0 + org.opencontainers.image.vendor=Hyperledger + org.opencontainers.image.version=${{ needs.set-docker-tags.outputs.tag_version }} + org.opencontainers.image.visibility=public + tags: | + ${{ needs.set-docker-tags.outputs.ghcr_image }}:${{ needs.set-docker-tags.outputs.tag_version }} + ${{ needs.set-docker-tags.outputs.ghcr_image }}:latest diff --git a/packages/cactus-plugin-satp-hermes/README.md b/packages/cactus-plugin-satp-hermes/README.md index e5a4ab9b75..3a05c3f1d4 100644 --- a/packages/cactus-plugin-satp-hermes/README.md +++ b/packages/cactus-plugin-satp-hermes/README.md @@ -261,6 +261,20 @@ docker compose \ --build ``` +To push the current version to the official repo, run (tested in MacOS): +```sh +IMAGE_NAME=ghcr.io/hyperledger-cacti/satp-hermes-gateway +DEV_TAG="$(date -u +"%Y-%m-%dT%H-%M-%S")-dev-$(git rev-parse --short HEAD)" + +echo "Building Docker image with name: $IMAGE_NAME:$DEV_TAG" + +docker build \ + --file ./packages/cactus-plugin-satp-hermes/satp-hermes-gateway.Dockerfile \ + ./packages/cactus-plugin-satp-hermes/ \ + --tag $IMAGE_NAME:$DEV_TAG \ + --tag $IMAGE_NAME:latest +``` + > The `--build` flag is going to save you 99% of the time from docker compose caching your image builds against your will or knowledge during development. ## Contributing diff --git a/packages/cactus-plugin-satp-hermes/src/main/typescript/generated/SATPWrapperContract.ts b/packages/cactus-plugin-satp-hermes/src/main/typescript/generated/SATPWrapperContract.ts index 74b5cfc08c..4ae4af7732 100755 --- a/packages/cactus-plugin-satp-hermes/src/main/typescript/generated/SATPWrapperContract.ts +++ b/packages/cactus-plugin-satp-hermes/src/main/typescript/generated/SATPWrapperContract.ts @@ -1,12 +1,12 @@ -import BN from 'bn.js'; -import BigNumber from 'bignumber.js'; +import BN from "bn.js"; +import BigNumber from "bignumber.js"; import { PromiEvent, TransactionReceipt, EventResponse, EventData, Web3ContractContext, -} from 'ethereum-abi-types-generator'; +} from "ethereum-abi-types-generator"; export interface CallOptions { from?: string; @@ -31,12 +31,12 @@ export interface MethodPayableReturnContext { send(options: SendOptions): PromiEvent; send( options: SendOptions, - callback: (error: Error, result: any) => void + callback: (error: Error, result: any) => void, ): PromiEvent; estimateGas(options: EstimateGasOptions): Promise; estimateGas( options: EstimateGasOptions, - callback: (error: Error, result: any) => void + callback: (error: Error, result: any) => void, ): Promise; encodeABI(): string; } @@ -46,7 +46,7 @@ export interface MethodConstantReturnContext { call(options: CallOptions): Promise; call( options: CallOptions, - callback: (error: Error, result: TCallReturn) => void + callback: (error: Error, result: TCallReturn) => void, ): Promise; encodeABI(): string; } @@ -60,60 +60,60 @@ export type ContractContext = Web3ContractContext< SATPWrapperContractEvents >; export type SATPWrapperContractEvents = - | 'Assign' - | 'Burn' - | 'Changed' - | 'Lock' - | 'Mint' - | 'OwnershipTransferred' - | 'Unlock' - | 'Unwrap' - | 'Wrap'; + | "Assign" + | "Burn" + | "Changed" + | "Lock" + | "Mint" + | "OwnershipTransferred" + | "Unlock" + | "Unwrap" + | "Wrap"; export interface SATPWrapperContractEventsContext { Assign( parameters: { filter?: { tokenId?: string | string[] }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; Burn( parameters: { filter?: { tokenId?: string | string[] }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; Changed( parameters: { filter?: { id?: string | string[] }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; Lock( parameters: { filter?: { tokenId?: string | string[] }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; Mint( parameters: { filter?: { tokenId?: string | string[] }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; OwnershipTransferred( parameters: { @@ -122,57 +122,57 @@ export interface SATPWrapperContractEventsContext { newOwner?: string | string[]; }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; Unlock( parameters: { filter?: { tokenId?: string | string[] }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; Unwrap( parameters: { filter?: { tokenId?: string | string[] }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; Wrap( parameters: { filter?: { tokenId?: string | string[] }; fromBlock?: number; - toBlock?: 'latest' | number; + toBlock?: "latest" | number; topics?: string[]; }, - callback?: (error: Error, event: EventData) => void + callback?: (error: Error, event: EventData) => void, ): EventResponse; } export type SATPWrapperContractMethodNames = - | 'new' - | 'assign' - | 'bridge_address' - | 'burn' - | 'getAllAssetsIDs' - | 'getToken' - | 'lock' - | 'mint' - | 'owner' - | 'renounceOwnership' - | 'tokens' - | 'tokensInteractions' - | 'transferOwnership' - | 'unlock' - | 'unwrap' - | 'wrap' - | 'wrap'; + | "new" + | "assign" + | "bridge_address" + | "burn" + | "getAllAssetsIDs" + | "getToken" + | "lock" + | "mint" + | "owner" + | "renounceOwnership" + | "tokens" + | "tokensInteractions" + | "transferOwnership" + | "unlock" + | "unwrap" + | "wrap" + | "wrap"; export interface TokenResponse { contractAddress: string; tokenType: string; @@ -243,7 +243,7 @@ export interface SATPWrapperContract { * Type: constructor * @param _bridge_address Type: address, Indexed: false */ - 'new'(_bridge_address: string): MethodReturnContext; + "new"(_bridge_address: string): MethodReturnContext; /** * Payable: false * Constant: false @@ -256,7 +256,7 @@ export interface SATPWrapperContract { assign( tokenId: string, receiver_account: string, - amount: string + amount: string, ): MethodReturnContext; /** * Payable: false @@ -339,7 +339,7 @@ export interface SATPWrapperContract { */ tokensInteractions( parameter0: string, - parameter1: string | number + parameter1: string | number, ): MethodConstantReturnContext; /** * Payable: false @@ -382,7 +382,7 @@ export interface SATPWrapperContract { tokenType: string | number, tokenId: string, owner: string, - interactions: InteractionsRequest[] + interactions: InteractionsRequest[], ): MethodReturnContext; /** * Payable: false @@ -398,6 +398,6 @@ export interface SATPWrapperContract { contractAddress: string, tokenType: string | number, tokenId: string, - owner: string + owner: string, ): MethodReturnContext; } diff --git a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/gateway-init-startup.test.ts b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/gateway-init-startup.test.ts index fee7cacb79..de17060d19 100644 --- a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/gateway-init-startup.test.ts +++ b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/gateway-init-startup.test.ts @@ -228,7 +228,7 @@ describe("SATPGateway initialization", () => { expect(loggerSpy).toHaveBeenCalledWith("mockHook"); expect(mockHookFn).toHaveBeenCalled(); - // For now, technically not needed. However if we use more tests with loggerSpy, conflicts could arise. + // For now, technically not needed. However if we use more tests with loggerSpy, conflicts could arise. // This is a reminder to restore the spy after each test loggerSpy.mockRestore(); }); @@ -382,8 +382,9 @@ describe("SATPGateway startup", () => { expect(result).toBeDefined(); expect(result.status).toBe(200); } catch (error) { - logger.error `Error: ${error}`; + logger.error`Error: ${error}`; } finally { + // todo error in the test, something was not properly shutdown await gateway.shutdown(); await httpServer2.closeAllConnections(); await apiServer1.shutdown(); diff --git a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-e2e-transfer-1-gateway-dockerization.test.ts b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-e2e-transfer-1-gateway-dockerization.test.ts index 5ee3d65e24..4fc2b24e48 100644 --- a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-e2e-transfer-1-gateway-dockerization.test.ts +++ b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-e2e-transfer-1-gateway-dockerization.test.ts @@ -181,7 +181,7 @@ describe("SATPGateway sending a token from Besu to Fabric", () => { // gatewayRunner setup: const gatewayRunnerOptions: ISATPGatewayRunnerConstructorOptions = { containerImageVersion: "latest", - containerImageName: "ghcr.io/hyperledger/cacti-satp-hermes-gateway", + containerImageName: "rafaelapb/cacti-satp-hermes-gateway", logLevel, emitContainerLogs: true, configFile: files.configFile, diff --git a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-e2e-transfer-2-gateways-dockerization.test.ts b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-e2e-transfer-2-gateways-dockerization.test.ts index a0150faa94..27292846d3 100644 --- a/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-e2e-transfer-2-gateways-dockerization.test.ts +++ b/packages/cactus-plugin-satp-hermes/src/test/typescript/integration/satp-e2e-transfer-2-gateways-dockerization.test.ts @@ -246,7 +246,7 @@ describe("SATPGateway sending a token from Besu to Fabric", () => { // gatewayRunner1 setup: const gatewayRunnerOptions1: ISATPGatewayRunnerConstructorOptions = { containerImageVersion: "latest", - containerImageName: "ghcr.io/hyperledger/cacti-satp-hermes-gateway", + containerImageName: "rafaelapb/cacti-satp-hermes-gateway", logLevel, emitContainerLogs: true, configFile: files1.configFile,