diff --git a/.github/workflows/build-images.reusable.yaml b/.github/workflows/build-images.reusable.yaml new file mode 100644 index 000000000..c4c0dac93 --- /dev/null +++ b/.github/workflows/build-images.reusable.yaml @@ -0,0 +1,42 @@ +name: Build and Push Docker Image + +on: + workflow_call: + inputs: + directory: + required: true + type: string + image_tags: + required: true + type: string + +jobs: + build-and-push-image: + name: Build and Push Docker Image + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: "16" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v1 + with: + username: ${{ secrets.IOTALEDGER_DOCKER_USERNAME }} + password: ${{ secrets.IOTALEDGER_DOCKER_PASSWORD }} + + - name: Build and push Docker image for ${{ inputs.directory }} + uses: docker/build-push-action@v2 + with: + context: ./${{ inputs.directory }} + file: ./${{ inputs.directory }}/Dockerfile + push: true + tags: ${{ inputs.image_tags }} + no-cache: true diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml deleted file mode 100644 index 97cf5d564..000000000 --- a/.github/workflows/build.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Build All with Node versions 16.16, 16.20.2 - -on: - push: - branches: [main, dev] - paths: - - "api/**" - - "client/**" - - ".github/workflows/build.yaml" - -concurrency: - group: build-${{ github.ref }} - cancel-in-progress: true - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - node: [ '16.16', '16.20.2' ] - name: Node ${{ matrix.node }} - steps: - - uses: actions/checkout@v2 - - name: Setup Node ${{ matrix.node }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node }} - - name: npm 8 - run: npm install -g npm@8 - - name: Build - run: | - cd client - npm install - npm run build - cd ../api - npm install - npm run build diff --git a/.github/workflows/create-draft-release.reusable.yaml b/.github/workflows/create-draft-release.reusable.yaml new file mode 100644 index 000000000..40dc71615 --- /dev/null +++ b/.github/workflows/create-draft-release.reusable.yaml @@ -0,0 +1,75 @@ +name: Create Draft Release + +on: + workflow_call: + inputs: + name: + required: true + type: string + version_tag: + required: true + type: string + +jobs: + github_draft_release: + name: Create Draft Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Prepare repository tags + run: | + if git rev-parse --is-shallow-repository | grep -q 'true'; then + git fetch --prune --unshallow --tags -f + else + git fetch --prune --tags -f + fi + + - name: Build changelog + id: build_changelog + run: | + echo "Building changelog..." + + # Create a changelog file with a header: + echo "# Changelog" > CHANGELOG.md + + # Check repository tags and the last tagged commit + n_tags=`git tag -l 'v*' --sort=-v:refname | wc -l` + prev_tag=`git tag -l 'v*' --sort=-v:refname | sed '2q;d'` + if [ $n_tags -eq 1 ]; then + last_commit=`git rev-list --max-parents=0 HEAD` + else + last_commit=`git rev-list -n 1 $prev_tag` + fi + + # Fill the changelog file with the commits since the last tag + # Set max tries to equal the maximum number of commits as protection + max_tries=`git rev-list --count HEAD` + i=0 + while [ `git rev-parse HEAD~$i` != $last_commit ] && [ $i -lt $((max_tries-1)) ] + do + echo '- ' `git show -s --format=%s HEAD~$i` >> CHANGELOG.md + i=$((i+1)) + done + + # Set the complete changelog url + echo >> CHANGELOG.md + compare="" + if [ $n_tags -eq 1 ]; then + compare=$last_commit + else + compare=$prev_tag + fi + compare="${compare}...`git tag -l 'v*' --sort=-v:refname | sed '1q;d'`" + echo "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${compare}" >> CHANGELOG.md + + echo "Changelog built successfully." + + - name: Create Draft Release + uses: softprops/action-gh-release@v1 + with: + name: ${{ inputs.name }} + tag_name: ${{ inputs.version_tag }} + draft: true + body_path: CHANGELOG.md diff --git a/.github/workflows/nova-docker-deploy.yaml b/.github/workflows/nova-docker-deploy.yaml deleted file mode 100644 index 5804fad5e..000000000 --- a/.github/workflows/nova-docker-deploy.yaml +++ /dev/null @@ -1,72 +0,0 @@ -name: Nova Deploy Workflow - -on: - workflow_dispatch: - inputs: - deployment: - type: boolean - description: 'Deploy after build?' - required: false - default: false - environment: - type: choice - description: 'Select the environment to deploy to' - options: - - nova - required: false - default: nova - push: - branches: - - nova - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - - name: Login to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.IOTALEDGER_DOCKER_USERNAME }} - password: ${{ secrets.IOTALEDGER_DOCKER_PASSWORD }} - - - name: Get the short commit hash - run: | - COMMIT_HASH=$(git rev-parse --short HEAD) - echo "VERSION=$COMMIT_HASH" >> $GITHUB_ENV - - - name: Set up Environment Variable - run: echo "DEPLOY_ENV=${{ github.event.inputs.environment }}" >> $GITHUB_ENV - - - name: Build and push API Docker image - uses: docker/build-push-action@v2 - with: - context: ./api - file: ./api/Dockerfile - push: true - tags: iotaledger/explorer-api:${{ env.VERSION }} - no-cache: true - - - name: Build and push Client Docker image - uses: docker/build-push-action@v2 - with: - context: ./client - file: ./client/Dockerfile - push: true - tags: iotaledger/explorer-client:${{ env.VERSION }} - no-cache: true - - - name: Add SSH key - uses: webfactory/ssh-agent@v0.5.2 - with: - ssh-private-key: ${{ secrets.UPDATER_SSH_PRIVATE_KEY }} - - - name: Deploy to Server - if: ${{ github.event.inputs.deployment }} - run: | - ssh -o StrictHostKeyChecking=no updater@${{ secrets.EXPLORER_NOVA_GATEWAY }} "${{ env.DEPLOY_ENV }} ${{ env.VERSION }}" diff --git a/.github/workflows/release-production.yaml b/.github/workflows/release-production.yaml new file mode 100644 index 000000000..f939f98e0 --- /dev/null +++ b/.github/workflows/release-production.yaml @@ -0,0 +1,58 @@ +name: Release Explorer to Production + +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+" + - "!v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+" + +jobs: + set_tags: + name: Set Tags + runs-on: ubuntu-latest + outputs: + version_tag: ${{ steps.set_version_tag.outputs.version_tag }} + steps: + - name: Set up the version tag for docker images + id: set_version_tag + run: | + echo "VERSION_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + + use-reusable-workflow: + strategy: + matrix: + directory: [api, client] + name: Build Images + needs: set_tags + uses: ./.github/workflows/build-images.reusable.yaml + with: + directory: ${{ matrix.directory }} + image_tags: | + iotaledger/explorer-${{ matrix.directory }}:${{ needs.set_tags.outputs.version_tag }} + iotaledger/explorer-${{ matrix.directory }}:latest + secrets: inherit + + deploy_to_server: + name: Deploy Production to Server + needs: [set_tags, use-reusable-workflow] + runs-on: ubuntu-latest + strategy: + matrix: + environment: [prod, shimmer-prod] + steps: + - name: Add SSH key + uses: webfactory/ssh-agent@v0.5.2 + with: + ssh-private-key: ${{ secrets.UPDATER_SSH_PRIVATE_KEY }} + + - name: Deploy to Server + run: | + ssh -o StrictHostKeyChecking=no updater@${{ secrets.EXPLORER_GATEWAY }} "${{ matrix.environment }} ${{ needs.set_tags.outputs.version_tag }}" + + create_draft_release: + name: Create Draft Release + needs: [set_tags, use-reusable-workflow, deploy_to_server] + uses: ./.github/workflows/create-draft-release.reusable.yaml + with: + name: Explorer ${{ needs.set_tags.outputs.version_tag }} + version_tag: ${{ needs.set_tags.outputs.version_tag }} diff --git a/.github/workflows/release-staging.yaml b/.github/workflows/release-staging.yaml new file mode 100644 index 000000000..8556b8d54 --- /dev/null +++ b/.github/workflows/release-staging.yaml @@ -0,0 +1,71 @@ +name: Release Explorer to Staging + +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+" # Versioning pattern 'v1.0.0-rc.0' + workflow_dispatch: + inputs: + tag: + description: "Tag" + required: true + default: "v1.0.0-rc.0" + +jobs: + set_tags: + name: Set Tags + runs-on: ubuntu-latest + outputs: + version_tag: ${{ steps.set_version_tag.outputs.version_tag }} + steps: + - name: Checkout + uses: actions/checkout@v2 + + # If the workflow was triggered by a tag, use the tag as the version. + # Otherwise, use the tag from the workflow_dispatch event. + - name: Set up the version tag for docker images + id: set_version_tag + run: | + if [ "${{ github.event_name }}" = "push" ]; then + echo "VERSION_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "VERSION_TAG=${{ github.event.inputs.tag }}" >> $GITHUB_OUTPUT + fi + + use-reusable-workflow: + strategy: + matrix: + directory: [api, client] + name: Build Image + needs: set_tags + uses: ./.github/workflows/build-images.reusable.yaml + with: + directory: ${{ matrix.directory }} + image_tags: | + iotaledger/explorer-${{ matrix.directory }}:${{ needs.set_tags.outputs.version_tag }} + secrets: inherit + + deploy_to_server: + name: Deploy Staging to Server + needs: [set_tags, use-reusable-workflow] + runs-on: ubuntu-latest + strategy: + matrix: + environment: [staging, shimmer-staging] + steps: + - name: Add SSH key + uses: webfactory/ssh-agent@v0.5.2 + with: + ssh-private-key: ${{ secrets.UPDATER_SSH_PRIVATE_KEY }} + + - name: Deploy to Server + run: | + ssh -o StrictHostKeyChecking=no updater@${{ secrets.EXPLORER_GATEWAY }} "${{ matrix.environment }} ${{ needs.set_tags.outputs.version_tag }}" + + create_draft_release: + name: Create Draft Release + needs: [set_tags, use-reusable-workflow, deploy_to_server] + uses: ./.github/workflows/create-draft-release.reusable.yaml + with: + name: Explorer ${{ needs.set_tags.outputs.version_tag }} + version_tag: ${{ needs.set_tags.outputs.version_tag }} diff --git a/package.json b/package.json index 2dfbff78c..737fdc362 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,7 @@ { "name": "explorer", + "description": "Tangle Explorer", + "version": "3.3.2", "scripts": { "setup:client": "cd client && npm install && npm run postinstall", "setup:api": "cd api && npm install && npm run build-compile && npm run build-config", @@ -7,7 +9,8 @@ "clear": "rimraf api/node_modules api/dist client/node_modules client/build", "dev": "concurrently 'cd api && npm run start-dev' 'cd client && npm run start'", "prepare": "husky install", - "format": "concurrently 'cd api && npm run format' 'cd client && npm run format'" + "format": "concurrently 'cd api && npm run format' 'cd client && npm run format'", + "tag:release": "./scripts/tag_release.sh" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^6.18.1", diff --git a/scripts/tag_release.sh b/scripts/tag_release.sh new file mode 100755 index 000000000..8fce4cb1d --- /dev/null +++ b/scripts/tag_release.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# Read target version from command line +TARGET_VERSION=$1 +CURRENT_VERSION=$(sed -n 's/.*"version": "\([^"]*\)".*/\1/p' package.json) + +if [[ -z $TARGET_VERSION ]]; then + echo "Current version (root) is v$CURRENT_VERSION" + read -p "Please specify target version: " TARGET_VERSION + read -n 1 -p "Confirm version change 'v$CURRENT_VERSION' -> 'v$TARGET_VERSION' ? (Enter): " CONFIRM_VERSION + + if [[ $CONFIRM_VERSION != "" ]]; then + echo "Aborting..." + exit 1 + fi +else + echo "Target version: v$TARGET_VERSION" +fi + +echo "Bumping version in package.json..." +sed -i.bak "4s/version\": \"\(.*\)\"/version\": \"$TARGET_VERSION\"/g" package.json +rm package.json.bak + +echo "Bumping version in api/package.json..." +cd "./api" +sed -i.bak "4s/version\": \"\(.*\)\"/version\": \"$TARGET_VERSION\"/g" package.json +rm package.json.bak + +echo "Bumping version in client/package.json..." +cd "../client" +sed -i.bak "4s/version\": \"\(.*\)\"/version\": \"$TARGET_VERSION\"/g" package.json +rm package.json.bak +cd "../" + +read -n 1 -p "Confirm making a bump commit and tagging with 'v$TARGET_VERSION' ? (Enter): " CONFIRM_BUMP + +if [[ $CONFIRM_BUMP != "" ]]; then + echo "Aborting..." + exit 1 +fi + +cd "./api" +npm i +cd "../client" +npm i +cd "../" + +echo "Making a bump commit..." +files_to_add=("package.json" "package-lock.json") +folders_to_add=("." "api" "client") +for folder in "${folders_to_add[@]}" +do + for file in "${files_to_add[@]}" + do + git add "$folder/$file" + done +done + +git commit -S -m "chore: bump version to v$TARGET_VERSION" + +echo "Tagging commit with 'v$TARGET_VERSION'..." +git tag v$TARGET_VERSION + +read -n 1 -p "Do you want to push branch and tags ? (Enter): " CONFIRM_PUSH +if [[ $CONFIRM_PUSH != "" ]]; then + echo "Exiting without pushing..." + exit 1 +fi + +echo "Pushing branch and tags..." +git push +git push origin refs/tags/v$TARGET_VERSION +echo "Done!" +