diff --git a/.github/actions/ensure-docker-image/action.yaml b/.github/actions/ensure-docker-image/action.yaml new file mode 100644 index 00000000..b3c6f41c --- /dev/null +++ b/.github/actions/ensure-docker-image/action.yaml @@ -0,0 +1,83 @@ +name: "Ensure docker image" +description: + "Checks if image with specific tag exists in the github container registry. + If it does not exists builds and pushes it." + +inputs: + gh-token: + description: "Github token used to push the image" + required: true + default: "" + + registry: + description: "Github registry" + required: true + default: "ghcr.io" + + repository: + description: "Github repository" + required: true + default: "${{ github.repository }}" + + image-name: + description: "Image name" + required: true + default: "" + + image-tag: + description: "Image tag" + required: true + default: "" + + dockerfile: + description: "Dockerfile path" + required: true + default: "" + +outputs: + tag: + description: "The latest tag which should be used" + value: ${{ steps.tag.outputs.tag }} + +runs: + using: "composite" + steps: + - name: Check if image exists + shell: bash + run: |- + if docker manifest inspect ${{ inputs.registry }}/${{ inputs.repository }}/${{ inputs.image-name }}:${{ inputs.image-tag }} > /dev/null 2>&1; then + echo "Image exists. Skipping build & push steps." + echo "exists=true" >> $GITHUB_ENV + else + echo "exists=false" >> $GITHUB_ENV + fi + + - name: Checkout code + if: env.exists != 'true' + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + if: env.exists != 'true' + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container registry + if: env.exists != 'true' + uses: docker/login-action@v3 + with: + registry: ${{ inputs.registry }} + username: ${{ github.actor }} + password: ${{ inputs.gh-token}} + + - name: Build and push Docker image + if: env.exists != 'true' + uses: docker/build-push-action@v6 + with: + context: . + file: ${{ inputs.dockerfile }} + push: true + tags: ${{ inputs.registry }}/${{ inputs.repository }}/${{ inputs.image-name }}:${{ inputs.image-tag }} + + - name: Latest tag output + id: tag + shell: bash + run: echo "tag=${{ inputs.image-tag }}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml deleted file mode 100644 index db270a8a..00000000 --- a/.github/workflows/build.yaml +++ /dev/null @@ -1,175 +0,0 @@ -name: Build -# Builds new binary and creates release draft. -# A version is denoted with a protected tag. -on: - push: - # Only tags which match the protected tag pattern will trigger this workflow - tags: - - v*.*.* - -env: - VERSION_TAG: ${{ github.ref_name }} - ARTIFACT_BIN: "nolus.tar.gz" - AWS_REGISTRY_ID: "013603813222" - AWS_REGION: "us-east-1" - ERC_REGISTRY: "public.ecr.aws" - ERC_REGISTRY_ALIAS: "nolus" - ERC_REPOSITORY: "builder" - # make sure to update build-binary container tag as well - IMAGE_TAG: "1.22.3" - DOCKERFILE: ".github/images/builder.Dockerfile" - CHECKSUM_FILE: "sha256sum.txt" - METADATA_FILE: "${{ github.ref_name }}_binaries.json" - ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true - -jobs: - # Checks if builder image exists in docker registry - builder-exists: - name: Builder exists - runs-on: ubuntu-20.04 - container: amazon/aws-cli - outputs: - # 'failure' - when no image with such tag exists - # 'success' - image exists - status: ${{ steps.check.outcome }} - - steps: - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1-node16 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - - - name: Run check exist image - id: check - continue-on-error: true - run: | - aws ecr-public describe-images \ - --registry-id $AWS_REGISTRY_ID \ - --repository-name $ERC_REPOSITORY \ - --region $AWS_REGION \ - --image-ids=imageTag=$IMAGE_TAG - - # Builds and push builder image if it does not exist - builder-create: - name: Create builder image - needs: builder-exists - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@v3 - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1-node16 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - with: - registry-type: public - - - name: Create new image - shell: bash - run: | - if [[ ${{ needs.builder-exists.outputs.status }} == 'failure' ]] - then - docker build -t $ERC_REGISTRY/$ERC_REGISTRY_ALIAS/$ERC_REPOSITORY:$IMAGE_TAG -f $DOCKERFILE . - docker push $ERC_REGISTRY/$ERC_REGISTRY_ALIAS/$ERC_REPOSITORY:$IMAGE_TAG - else - echo "Image version $IMAGE_TAG exists. Skipping step..." - fi - - # Builds new version of the binary. - build-binary: - name: Build binary - needs: builder-create - runs-on: ubuntu-latest - container: - # image name needs to be hardcoded: https://github.com/orgs/community/discussions/26324 - image: "public.ecr.aws/nolus/builder:1.22.3" - - steps: - - uses: actions/checkout@v3 - - # This is to fix GIT not liking owner of the checkout dir - # Happens when executing not into the default container - - name: Set ownership - run: | - chown -R $(id -u):$(id -g) $PWD - - - name: Run build binary - run: | - make build - echo "Ensuring binary is statically linked ..." - file target/release/nolusd | grep "statically linked" - - - name: Prepare binary tar - run: | - tar -C target/release/ -czvf $ARTIFACT_BIN . - - - name: Upload binary tar - uses: actions/upload-artifact@v4 - with: - name: nolusd-tar-${{ env.VERSION_TAG }} - path: ${{ env.ARTIFACT_BIN }} - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: nolusd-${{ env.VERSION_TAG }} - path: target/release/nolusd - - # Add metadata for cosmovisor - add-meta: - name: Add metadata - needs: build-binary - runs-on: ubuntu-latest - steps: - - name: Download artifacts - uses: actions/download-artifact@v4 - - - name: Get binary checksum - run: | - CHECKSUM=$(shasum -a 256 nolusd-"${VERSION_TAG}"/nolusd) - echo "$CHECKSUM" > $CHECKSUM_FILE - HASH=$(echo "$CHECKSUM" | cut -d' ' -f1) - JSON="{\"binaries\": {\"linux/amd64\": \"https://github.com/nolus-protocol/nolus-core/releases/download/${VERSION_TAG}/nolusd?checksum=sha256:$HASH\"}}" - echo $JSON > $METADATA_FILE - - - name: Upload metadata - uses: actions/upload-artifact@v4 - with: - name: metadata - path: | - ${{ env.METADATA_FILE }} - ${{ env.CHECKSUM_FILE }} - - # Drafts a release - release: - name: Draft release - runs-on: ubuntu-latest - needs: [build-binary, add-meta] - permissions: write-all - - steps: - - name: Download artifacts - uses: actions/download-artifact@v4 - - - name: Display structure of downloaded files - run: ls -R - - # temporary using commit as version until it is merged. Updates node version v12 -> v16 - - uses: "marvinpinto/action-automatic-releases@6273874b61ebc8c71f1a61b2d98e234cf389b303" - with: - repo_token: "${{ secrets.GITHUB_TOKEN }}" - prerelease: false - draft: true - files: | - nolusd-tar-${{ env.VERSION_TAG }} - nolusd-${{ env.VERSION_TAG }} - metadata diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml deleted file mode 100644 index 7eaf4b10..00000000 --- a/.github/workflows/lint.yaml +++ /dev/null @@ -1,34 +0,0 @@ -name: Lint -on: - pull_request: - push: - tags: - - v* - branches: - - main - -jobs: - golangci: - name: Run golangci-lint - runs-on: ubuntu-latest - steps: - - uses: actions/setup-go@v4 - with: - go-version: 1.22 - - uses: actions/checkout@v3 - - name: golangci-lint - uses: golangci/golangci-lint-action@v3 - with: - version: v1.55.2 - # Optional: if set to true, then all caching functionality will be completely disabled, - # takes precedence over all other caching options. - skip-cache: true - - # Optional: if set to true, then the action won't cache or restore ~/go/pkg. - skip-pkg-cache: true - - # Optional: if set to true, then the action won't cache or restore ~/.cache/go-build. - skip-build-cache: true - - # Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'. - # install-mode: "goinstall" \ No newline at end of file diff --git a/.github/workflows/nolus-core.yaml b/.github/workflows/nolus-core.yaml new file mode 100644 index 00000000..0595887b --- /dev/null +++ b/.github/workflows/nolus-core.yaml @@ -0,0 +1,253 @@ +name: Nolus-Core + +on: + workflow_dispatch: + push: + branches: + - "**" # any branch + tags: + # triggers the final 'release' job + - "v*.*.*" # this is protected tag pattern + +env: + VERSION_TAG: ${{ github.ref_name }} + ARTIFACT_BIN: "nolus.tar.gz" + CHECKSUM_FILE: "sha256sum.txt" + METADATA_FILE: "${{ github.ref_name }}_binaries.json" + + # docker images + CONTAINER_REGISTRY: ghcr.io + BUILDER_IMAGE_TAG: "1.22.3" + BUILDER_IMAGE_NAME: "builder" + BUILDER_DOCKERFILE: ".github/images/builder.Dockerfile" + PROTOGEN_IMAGE_TAG: "0.2.0" + PROTOGEN_IMAGE_NAME: "protogen" + PROTOGEN_DOCKERFILE: ".github/images/protogen.Dockerfile" + +permissions: + contents: read + +jobs: + protogen-image: + name: Ensure protogen image exists + runs-on: ubuntu-latest + outputs: + tag: ${{ steps.ensure.outputs.tag }} + steps: + - uses: actions/checkout@v4 + + - uses: "./.github/actions/ensure-docker-image" + id: ensure + with: + gh-token: ${{ secrets.GITHUB_TOKEN }} + dockerfile: ${{ env.PROTOGEN_DOCKERFILE }} + image-name: ${{ env.PROTOGEN_IMAGE_NAME }} + image-tag: ${{ env.PROTOGEN_IMAGE_TAG }} + + proto-lint: + name: Lint protobuf files + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + + - uses: bufbuild/buf-setup-action@v1.39.0 + + - uses: bufbuild/buf-lint-action@v1 + with: + input: "proto" + + proto-break-check: + name: Detect protobuf breaking changes + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: bufbuild/buf-setup-action@v1.39.0 + + - uses: bufbuild/buf-breaking-action@v1.1.4 + with: + input: "proto" + against: "https://github.com/${{ github.repository }}.git#branch=main,ref=HEAD~1,subdir=proto" + + builder-image: + name: Ensure builder image exists + runs-on: ubuntu-latest + outputs: + tag: ${{ steps.ensure.outputs.tag }} + steps: + - uses: actions/checkout@v4 + + - uses: "./.github/actions/ensure-docker-image" + id: ensure + with: + gh-token: ${{ secrets.GITHUB_TOKEN }} + dockerfile: ${{ env.BUILDER_DOCKERFILE }} + image-name: ${{ env.BUILDER_IMAGE_NAME }} + image-tag: ${{ env.BUILDER_IMAGE_TAG }} + + golang-lint: + name: Lint Go files + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v5 + with: + go-version: 1.22 + cache: false + + - uses: actions/checkout@v4 + + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.55.2 + # Optional: if set to true, then all caching functionality will be completely disabled, + # takes precedence over all other caching options. + skip-cache: true + + # Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'. + install-mode: "goinstall" + + test-unit: + name: Run unit tests + runs-on: ubuntu-latest + needs: [golang-lint, builder-image, protogen-image, proto-lint, proto-break-check] + steps: + - uses: actions/setup-go@v5 + with: + go-version: 1.22 + cache: false + + - uses: actions/checkout@v4 + + - run: | + make test-unit + + - name: Archive code coverage results + uses: actions/upload-artifact@v4 + with: + name: coverage-results-out + path: | + cover.out + retention-days: 1 + + test-unit-coverage: + name: Code coverage reports + needs: test-unit + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v5 + with: + go-version: 1.22 + cache: false + + - uses: actions/checkout@v4 + + - name: Download coverage result + uses: actions/download-artifact@v4 + with: + name: coverage-results-out + + - run: | + make test-unit-coverage + make test-unit-coverage-report + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: coverage-reports + path: | + coverage.xml + coverage.html + + build-binary: + name: Build binary + runs-on: ubuntu-latest + needs: [test-unit-coverage, builder-image] + container: + image: "ghcr.io/${{ github.repository }}/builder:${{ needs.builder-image.outputs.tag }}" + + steps: + - uses: actions/checkout@v4 + + # This is to fix GIT not liking owner of the checkout dir + # Happens when executing not into the default container + - name: Set ownership + run: | + chown -R $(id -u):$(id -g) $PWD + + - name: Run build binary + run: | + make build + echo "Ensuring binary is statically linked ..." + file target/release/nolusd | grep "statically linked" + + - name: Prepare binary tar + run: | + tar -C target/release/ -czvf $ARTIFACT_BIN . + + - name: Upload binary tar + uses: actions/upload-artifact@v4 + with: + name: nolusd-tar-${{ env.VERSION_TAG }} + path: ${{ env.ARTIFACT_BIN }} + + - name: Upload binary + uses: actions/upload-artifact@v4 + with: + name: nolusd-${{ env.VERSION_TAG }} + path: target/release/nolusd + + # Add metadata for cosmovisor + add-meta: + name: Add metadata + runs-on: ubuntu-latest + needs: build-binary + + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + + - name: Get binary checksum + run: | + CHECKSUM=$(shasum -a 256 nolusd-"${VERSION_TAG}"/nolusd) + echo "$CHECKSUM" > $CHECKSUM_FILE + HASH=$(echo "$CHECKSUM" | cut -d' ' -f1) + JSON="{\"binaries\": {\"linux/amd64\": \"https://github.com/nolus-protocol/nolus-core/releases/download/${VERSION_TAG}/nolusd?checksum=sha256:$HASH\"}}" + echo $JSON > $METADATA_FILE + + - name: Upload metadata + uses: actions/upload-artifact@v4 + with: + name: metadata + path: | + ${{ env.METADATA_FILE }} + ${{ env.CHECKSUM_FILE }} + + # Drafts a Github release + # Only tags which match the protected tag pattern will trigger this job + # Tag pattern: v*.*.* + release: + name: Draft release + if: github.ref_type == 'tag' + runs-on: ubuntu-latest + needs: add-meta + permissions: write-all + + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + + - name: Display structure of downloaded files + run: ls -R + + # temporary using commit as version until it is merged. Updates node version v12 -> v16 + - uses: "marvinpinto/action-automatic-releases@6273874b61ebc8c71f1a61b2d98e234cf389b303" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + prerelease: false + draft: true + files: | + nolusd-tar-${{ env.VERSION_TAG }} + nolusd-${{ env.VERSION_TAG }} + metadata diff --git a/.github/workflows/proto.yaml b/.github/workflows/proto.yaml deleted file mode 100644 index 10631d2f..00000000 --- a/.github/workflows/proto.yaml +++ /dev/null @@ -1,104 +0,0 @@ -name: Protobuf -# Protobuf runs buf (https://buf.build/) lint and check-breakage -# This workflow is only run when a .proto file has been changed -on: - workflow_dispatch: - pull_request: - paths: - - "proto/**" - -permissions: - contents: read - -env: - AWS_REGISTRY_ID: "013603813222" - AWS_REGION: "us-east-1" - ERC_REGISTRY: "public.ecr.aws" - ERC_REGISTRY_ALIAS: "nolus" - ERC_REPOSITORY: "protogen" - IMAGE_TAG: "0.2.0" - DOCKERFILE: ".github/images/protogen.Dockerfile" - ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true -jobs: - # Checks if protogen image exists in docker registry - protogen-exists: - name: Check protogen exists - runs-on: ubuntu-20.04 - container: amazon/aws-cli - outputs: - # 'failure' - when no image with such tag exists - # 'success' - image exists - status: ${{ steps.check.outcome }} - - steps: - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1-node16 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - - - name: Run check exist image - id: check - continue-on-error: true - run: | - aws ecr-public describe-images \ - --registry-id $AWS_REGISTRY_ID \ - --repository-name $ERC_REPOSITORY \ - --region $AWS_REGION \ - --image-ids=imageTag=$IMAGE_TAG - - # Builds and push protogen image if it does not exist - protogen-create: - name: Create protogen image - needs: protogen-exists - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@v3 - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v1-node16 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - aws-region: ${{ env.AWS_REGION }} - - - name: Login to Amazon ECR - id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 - with: - registry-type: public - - - name: Create new image - shell: bash - run: | - if [[ ${{ needs.protogen-exists.outputs.status }} == 'failure' ]] - then - docker build -t $ERC_REGISTRY/$ERC_REGISTRY_ALIAS/$ERC_REPOSITORY:$IMAGE_TAG -f $DOCKERFILE . - docker push $ERC_REGISTRY/$ERC_REGISTRY_ALIAS/$ERC_REPOSITORY:$IMAGE_TAG - else - echo "Image version $IMAGE_TAG exists. Skipping step..." - fi - - proto-lint: - name: Lint protobuf files - runs-on: ubuntu-20.04 - timeout-minutes: 5 - steps: - - uses: actions/checkout@v3 - - uses: bufbuild/buf-setup-action@v1.9.0 - - uses: bufbuild/buf-lint-action@v1 - with: - input: "proto" - - proto-break-check: - name: Detect breaking changes - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v3 - - uses: bufbuild/buf-setup-action@v1.9.0 - - uses: bufbuild/buf-breaking-action@v1 - with: - input: "proto" - against: "https://github.com/${{ github.repository }}.git#branch=${{ github.event.pull_request.base.ref }},ref=HEAD~1,subdir=proto" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml deleted file mode 100644 index 3aa083a2..00000000 --- a/.github/workflows/test.yaml +++ /dev/null @@ -1,58 +0,0 @@ -name: Test -on: - pull_request: - push: - tags: - - v* - branches: - - main - -jobs: - test-unit: - name: Run unit tests - runs-on: ubuntu-latest - steps: - - uses: actions/setup-go@v4 - with: - go-version: 1.22 - - - uses: actions/checkout@v3 - - - run: | - make test-unit - - - name: Archive code coverage results - uses: actions/upload-artifact@v3 - with: - name: coverage-results-out - path: | - cover.out - retention-days: 1 - - test-unit-coverage: - name: Code coverage reports - needs: test-unit - runs-on: ubuntu-latest - steps: - - uses: actions/setup-go@v4 - with: - go-version: 1.22 - - - uses: actions/checkout@v3 - - - name: Download coverage result - uses: actions/download-artifact@v3 - with: - name: coverage-results-out - - - run: | - make test-unit-coverage - make test-unit-coverage-report - - - name: Upload artifacts - uses: actions/upload-artifact@v3 - with: - name: coverage-reports - path: | - coverage.xml - coverage.html