diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 81650fc53..9d360c6a4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,18 +1,38 @@ -name: build -on: +name: build-and-test + +on: push: - branches: [ bcn-multiplatform ] + tags: + - "*" jobs: + extract-version: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.extract.outputs.version }} + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Extract version from package.json + id: extract + run: | + VERSION=$(node -p "require('./package.json').version") + echo "Extracted version: $VERSION" + echo "version=[\"$VERSION\"]" >> $GITHUB_OUTPUT build: + needs: extract-version runs-on: ubuntu-latest strategy: matrix: - version: - - '0.10.0-alpha.4' + version: ${{ fromJson(needs.extract-version.outputs.version) }} folder: - - 'packages/node' + - "packages/node" fail-fast: false + outputs: + temp_tag: ${{ steps.prepare.outputs.temp_tag }} + final_tags: ${{ steps.prepare.outputs.final_tags }} + steps: - name: Set up Docker Buildx uses: crazy-max/ghaction-docker-buildx@v1 @@ -30,46 +50,141 @@ jobs: - name: Prepare Docker build id: prepare run: | - function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } - BCN_VERSION=${{matrix.version}} - PLATFORMS="linux/amd64,linux/arm64/v8,linux/arm/v7" + PLATFORMS="linux/amd64,linux/arm64/v8" PUSH=true DOCKER_REPO=bcdb/bcn - - TAGS=("$DOCKER_REPO:${BCN_VERSION} $DOCKER_REPO:latest") - - echo "Building BCN_VERSION $BCN_VERSION/ for PLATFORMS ${PLATFORMS}/" - + TEMP_TAG="${DOCKER_REPO}:${BCN_VERSION}-pre-release" + FINAL_TAGS=("${DOCKER_REPO}:${BCN_VERSION} ${DOCKER_REPO}:latest") + echo "Building BCN_VERSION $BCN_VERSION for PLATFORMS ${PLATFORMS}" echo ::set-output name=build_date::$(date -u +'%Y-%m-%dT%H:%M:%SZ') echo ::set-output name=docker_platforms::${PLATFORMS} echo ::set-output name=push::${PUSH} - echo ::set-output name=tags::${TAGS[@]} + echo ::set-output name=temp_tag::${TEMP_TAG} + echo ::set-output name=final_tags::${FINAL_TAGS[@]} + echo "temp_tag=${TEMP_TAG}" >> $GITHUB_OUTPUT + echo "final_tags=${FINAL_TAGS[@]}" >> $GITHUB_OUTPUT - - name: Build Docker image + - name: Build and push temporary image + working-directory: ./ run: | - TAGS=(${{ steps.prepare.outputs.tags }}) - - echo "Build date: ${{ steps.prepare.outputs.build_date }}" - echo "Docker platform: ${{ steps.prepare.outputs.docker_platforms }}" - echo "Push: ${{ steps.prepare.outputs.push }}" - echo "Tags: ${{ steps.prepare.outputs.tags }}" - - echo docker buildx build --platform ${{ steps.prepare.outputs.docker_platforms }} \ - --output "type=image,push=${{steps.prepare.outputs.push}}" \ - --progress=plain \ - --build-arg "BUILD_DATE=${{ steps.prepare.outputs.build_date }}" \ - --build-arg "VCS_REF=${GITHUB_SHA::8}" \ - $(printf "%s" "${TAGS[@]/#/ --tag }" ) \ - ${{ matrix.folder }}/ - + docker buildx create --use docker buildx build --platform ${{ steps.prepare.outputs.docker_platforms }} \ --output "type=image,push=${{steps.prepare.outputs.push}}" \ --progress=plain \ - --build-arg "BUILD_DATE=${{ steps.prepare.outputs.build_date }}" \ - --build-arg "VCS_REF=${GITHUB_SHA::8}" \ - $(printf "%s" "${TAGS[@]/#/ --tag }" ) \ - ${{ matrix.folder }}/ + --tag ${{ steps.prepare.outputs.temp_tag }} \ + -f Dockerfile . + + - name: Debug temp_tag + run: | + echo "Temporary tag: ${{ steps.prepare.outputs.temp_tag }}" + + - name: Clear DockerHub credentials + run: | + rm -f ${HOME}/.docker/config.json + integration-tests: + needs: [build, extract-version] + runs-on: ubuntu-latest + strategy: + matrix: + version: ${{ fromJson(needs.extract-version.outputs.version) }} + platform: + - linux/amd64 + - linux/arm64 + outputs: + temp_tag: ${{ steps.prepare.outputs.temp_tag }} + final_tags: ${{ steps.prepare.outputs.final_tags }} + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Prepare Docker build + id: prepare + run: | + BCN_VERSION=${{matrix.version}} + DOCKER_REPO=bcdb/bcn + TEMP_TAG="${DOCKER_REPO}:${BCN_VERSION}-pre-release" + FINAL_TAGS=("${DOCKER_REPO}:${BCN_VERSION} ${DOCKER_REPO}:latest") + echo ::set-output name=temp_tag::${TEMP_TAG} + echo ::set-output name=final_tags::${FINAL_TAGS[@]} + echo "temp_tag=${TEMP_TAG}" >> $GITHUB_OUTPUT + echo "final_tags=${FINAL_TAGS[@]}" >> $GITHUB_OUTPUT + + - name: Debug temp_tag + run: | + echo "Temporary tag from build job: ${{ steps.prepare.outputs.temp_tag }}" + + - name: Pull temporary image + run: | + docker pull ${{ steps.prepare.outputs.temp_tag }} + + - name: Re-tag image for docker-compose + run: | + docker tag ${{ steps.prepare.outputs.temp_tag }} bitcoin-computer-node + echo "Re-tagged image as bitcoin-computer-node" + + - name: Copy configuration files + working-directory: packages/node + run: | + cp chain-setup/LTC/regtest/.env.example .env + echo "Copied .env.example to .env" + + cp chain-setup/LTC/regtest/litecoin.conf.example litecoin.conf + echo "Copied litecoin.conf.example to litecoin.conf" + + - name: Set up Docker Compose + run: | + sudo apt-get update && sudo apt-get install -y docker-compose + + - name: Install dependencies (npm install) + working-directory: packages/node + continue-on-error: true + run: | + npm install || echo "npm install failed, but continuing..." + + - name: Start services in regtest mode + working-directory: packages/node + run: | + npm run up & + echo "Waiting for services to start..." + sleep 20 + + - name: Run integration tests + working-directory: packages/node + run: | + npm run test + + - name: Clear DockerHub credentials + run: | + rm -f ${HOME}/.docker/config.json + + - name: Stop services + working-directory: packages/node + run: | + npm run down + + re-tag-and-push: + needs: [integration-tests] + runs-on: ubuntu-latest + if: always() && needs.integration-tests.result == 'success' + steps: + - name: Login into Docker Hub + env: + DOCKER_HUB_USERNAME: ${{ secrets.DOCKER_HUB_USERNAME }} + DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} + run: | + echo "${DOCKER_HUB_PASSWORD}" | docker login --username "${DOCKER_HUB_USERNAME}" --password-stdin + + - name: Set up Docker Buildx + uses: crazy-max/ghaction-docker-buildx@v1 + + - name: Re-tag and push final tags + run: | + TEMP_TAG="${{ needs.integration-tests.outputs.temp_tag }}" + FINAL_TAGS=(${{ needs.integration-tests.outputs.final_tags }}) + for TAG in "${FINAL_TAGS[@]}"; do + docker buildx imagetools create --tag "$TAG" "$TEMP_TAG" + done - name: Clear DockerHub credentials run: | diff --git a/package.json b/package.json index 7fce93616..4f738e5e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bitcoin-computer", - "version": "0.23.0-beta.0", + "version": "0.24.0-beta.0", "private": true, "description": "A Trustless Smart Contract System for Bitcoin and Litecoin", "homepage": "http://bitcoincomputer.io/", diff --git a/packages/node/.mocharc.json b/packages/node/.mocharc.json index c70d7a3f0..e57f73974 100644 --- a/packages/node/.mocharc.json +++ b/packages/node/.mocharc.json @@ -1,9 +1,6 @@ { "extension": ["ts"], - "node-option": [ - "experimental-specifier-resolution=node", - "loader=ts-node/esm" - ], + "node-option": ["experimental-specifier-resolution=node", "loader=ts-node/esm"], "require": ["dotenv/config"], "spec": "test/*.js", "timeout": "30000000" diff --git a/packages/node/docker-compose.yml b/packages/node/docker-compose.yml index 32206f044..26583d957 100644 --- a/packages/node/docker-compose.yml +++ b/packages/node/docker-compose.yml @@ -4,10 +4,10 @@ services: env_file: .env restart: always healthcheck: - test: [ "CMD-SHELL", "pg_isready -U ${POSTGRES_USER}" ] + test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER}'] # command: ["postgres", "-c", "log_statement=all"] ports: - - "${POSTGRES_PORT}:${POSTGRES_PORT}" + - '${POSTGRES_PORT}:${POSTGRES_PORT}' networks: - bcn environment: @@ -28,16 +28,12 @@ services: - ./chain-setup/${BCN_CHAIN}/${BCN_NETWORK}/blockchain-data:${BITCOIN_DATA_DIR} - ./${BITCOIN_CONF_FILE}:${BITCOIN_DATA_DIR}/${BITCOIN_CONF_FILE} bcn: - image: bitcoin-computer-node + image: bcdb/bcn env_file: .env restart: always build: ../../ healthcheck: - test: - [ - "CMD-SHELL", - "curl -f http://localhost:${BCN_PORT}/ || exit 1" - ] + test: ['CMD-SHELL', 'curl -f http://localhost:${BCN_PORT}/ || exit 1'] interval: 30s timeout: 10s retries: 3 @@ -69,7 +65,7 @@ services: - ./logs:/dist/packages/node/logs sync: command: npm run start:sync - image: bitcoin-computer-node + image: bcdb/bcn env_file: .env restart: always environment: diff --git a/packages/node/test/test.js b/packages/node/test/test.js index 650519025..c28aa7dc9 100644 --- a/packages/node/test/test.js +++ b/packages/node/test/test.js @@ -16,19 +16,22 @@ describe('Should work with chai', () => { expect(computer).an('object') }) - it('Should fund the client side library', async () => { + it('Should fund the client side library', async function () { + this.retries(3) const computer = new Computer(conf) await computer.faucet(1e7) expect((await computer.getBalance()).balance).eq(1e7) }) - it('Should send a transaction', async () => { + it('Should send a transaction', async function () { + this.retries(3) const computer = new Computer(conf) await computer.faucet(1e7) - expect(typeof await computer.send(1e6, new Computer(conf).getAddress())).eq('string') + expect(typeof (await computer.send(1e6, new Computer(conf).getAddress()))).eq('string') }) - it('Should return the balance of an address', async () => { + it('Should return the balance of an address', async function () { + this.retries(3) const computer = new Computer(conf) await computer.faucet(1e7) const balance = await new Computer(conf).getBalance(computer.getAddress()) @@ -51,9 +54,9 @@ describe('Should work with chai', () => { txId, inputsSatoshis: 0, outputsSatoshis: 1e7, - satoshis: 1e7 - } - ] + satoshis: 1e7, + }, + ], }) }) @@ -97,9 +100,9 @@ describe('Should work with chai', () => { txId, inputsSatoshis: 0, outputsSatoshis: 1e7, - satoshis: 1e7 - } - ] + satoshis: 1e7, + }, + ], }) }) })