From 3bd9547622a11620d7951f26152ba974bd04adef Mon Sep 17 00:00:00 2001 From: junkwarrior87 <115852752+junkwarrior87@users.noreply.github.com> Date: Mon, 25 Dec 2023 10:16:14 +0000 Subject: [PATCH] #1 change colors and update to newest blockscoutV2 --- .github/workflows/checks.yml | 171 ----------- .github/workflows/cleanup.yml | 33 -- .github/workflows/deploy-main.yml | 40 --- .github/workflows/deploy-review-l2.yml | 38 --- .github/workflows/deploy-review.yml | 38 --- .github/workflows/docker.yml | 23 ++ .github/workflows/e2e-tests.yml | 50 ---- .github/workflows/label-issues-in-release.yml | 282 ------------------ .github/workflows/pre-release.yml | 61 ---- .github/workflows/project-management.yml | 89 ------ .github/workflows/publish-image.yml | 64 ---- .github/workflows/release.yml | 86 ------ .github/workflows/stale-issues.yml | 29 -- .github/workflows/update-project-cards.yml | 240 --------------- .github/workflows/upload-source-maps.yml | 48 --- pages/_document.tsx | 6 +- public/icon.png | Bin 0 -> 21588 bytes public/logo.png | Bin 0 -> 12331 bytes theme/foundations/semanticTokens.ts | 2 +- ui/home/StatsItem.tsx | 5 +- ui/home/indicators/ChainIndicatorChart.tsx | 2 +- ui/home/indicators/ChainIndicators.tsx | 1 + ui/shared/LinkInternal.tsx | 2 +- ui/shared/Tabs/TabsWithScroll.tsx | 2 +- ui/shared/chart/ChartArea.tsx | 4 +- ui/shared/pagination/Pagination.tsx | 4 + ui/snippets/navigation/useColors.ts | 6 +- ui/snippets/topBar/TopBar.tsx | 2 +- 28 files changed, 46 insertions(+), 1282 deletions(-) delete mode 100644 .github/workflows/checks.yml delete mode 100644 .github/workflows/cleanup.yml delete mode 100644 .github/workflows/deploy-main.yml delete mode 100644 .github/workflows/deploy-review-l2.yml delete mode 100644 .github/workflows/deploy-review.yml create mode 100644 .github/workflows/docker.yml delete mode 100644 .github/workflows/e2e-tests.yml delete mode 100644 .github/workflows/label-issues-in-release.yml delete mode 100644 .github/workflows/pre-release.yml delete mode 100644 .github/workflows/project-management.yml delete mode 100644 .github/workflows/publish-image.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/stale-issues.yml delete mode 100644 .github/workflows/update-project-cards.yml delete mode 100644 .github/workflows/upload-source-maps.yml create mode 100644 public/icon.png create mode 100644 public/logo.png diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml deleted file mode 100644 index eb0810c8f5..0000000000 --- a/.github/workflows/checks.yml +++ /dev/null @@ -1,171 +0,0 @@ -name: Checks -on: - workflow_call: - workflow_dispatch: - pull_request: - types: [ opened, synchronize, unlabeled ] - paths-ignore: - - '.github/ISSUE_TEMPLATE/**' - - '.husky/**' - - '.vscode/**' - - 'deploy/**' - - 'docs/**' - - 'public/**' - - 'stub/**' - - 'tools/**' - -# concurrency: -# group: ${{ github.workflow }}__${{ github.job }}__${{ github.ref }} -# cancel-in-progress: true - -jobs: - code_quality: - name: Code quality - runs-on: ubuntu-latest - if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip checks') && !(github.event.action == 'unlabeled' && github.event.label.name != 'skip checks') }} - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Setup node - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: 'yarn' - - - name: Cache node_modules - uses: actions/cache@v3 - id: cache-node-modules - with: - path: | - node_modules - key: node_modules-${{ runner.os }}-${{ hashFiles('yarn.lock') }} - - - name: Install dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: yarn --frozen-lockfile --ignore-optional - - - name: Run ESLint - run: yarn lint:eslint - - - name: Compile TypeScript - run: yarn lint:tsc - - envs_validation: - name: ENV variables validation - runs-on: ubuntu-latest - needs: [ code_quality ] - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Setup node - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: 'yarn' - - - name: Cache node_modules - uses: actions/cache@v3 - id: cache-node-modules - with: - path: | - node_modules - key: node_modules-${{ runner.os }}-${{ hashFiles('yarn.lock') }} - - - name: Install dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: yarn --frozen-lockfile --ignore-optional - - - name: Install script dependencies - run: cd ./deploy/tools/envs-validator && yarn --frozen-lockfile --ignore-optional - - - name: Run validation tests - run: | - set +e - cd ./deploy/tools/envs-validator && yarn test - exitcode="$?" - echo "exitcode=$exitcode" >> $GITHUB_OUTPUT - exit "$exitcode" - - jest_tests: - name: Jest tests - needs: [ code_quality, envs_validation ] - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Setup node - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: 'yarn' - - - name: Cache node_modules - uses: actions/cache@v3 - id: cache-node-modules - with: - path: | - node_modules - key: node_modules-${{ runner.os }}-${{ hashFiles('yarn.lock') }} - - - name: Install dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: yarn --frozen-lockfile --ignore-optional - - - name: Run Jest - run: yarn test:jest - - pw_tests: - name: 'Playwright tests / Project: ${{ matrix.project }}' - needs: [ code_quality, envs_validation ] - runs-on: ubuntu-latest - container: - image: mcr.microsoft.com/playwright:v1.35.1-focal - - strategy: - fail-fast: false - matrix: - project: [ default, mobile, dark-color-mode ] - - steps: - - name: Install git-lfs - run: apt-get update && apt-get install git-lfs - - - name: Checkout repo - uses: actions/checkout@v3 - with: - lfs: 'true' - - - name: Setup node - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: 'yarn' - - - name: Cache node_modules - uses: actions/cache@v3 - id: cache-node-modules - with: - path: | - node_modules - key: node_modules-${{ runner.os }}-${{ hashFiles('yarn.lock') }} - - - name: Install dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: yarn --frozen-lockfile --ignore-optional - - - name: Run PlayWright - run: yarn test:pw:ci - env: - HOME: /root - PW_PROJECT: ${{ matrix.project }} - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v3 - with: - name: playwright-report-${{ matrix.project }} - path: playwright-report - retention-days: 10 \ No newline at end of file diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml deleted file mode 100644 index a8ed3ee27a..0000000000 --- a/.github/workflows/cleanup.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Cleanup environments - -on: - pull_request: - types: - - closed - - merged - workflow_dispatch: - -jobs: - cleanup_release: - uses: blockscout/blockscout-ci-cd/.github/workflows/cleanup_helmfile.yaml@master - with: - appName: review-l2-$GITHUB_REF_NAME_SLUG - globalEnv: review - helmfileDir: deploy - kubeConfigSecret: ci/data/dev/kubeconfig/k8s-dev - vaultRole: ci-dev - secrets: inherit - cleanup_l2_release: - uses: blockscout/blockscout-ci-cd/.github/workflows/cleanup_helmfile.yaml@master - with: - appName: review-$GITHUB_REF_NAME_SLUG - globalEnv: review - helmfileDir: deploy - kubeConfigSecret: ci/data/dev/kubeconfig/k8s-dev - vaultRole: ci-dev - secrets: inherit - cleanup_docker_image: - uses: blockscout/blockscout-ci-cd/.github/workflows/cleanup_docker.yaml@master - with: - dockerImage: review-$GITHUB_REF_NAME_SLUG - secrets: inherit diff --git a/.github/workflows/deploy-main.yml b/.github/workflows/deploy-main.yml deleted file mode 100644 index d8cf2b79b3..0000000000 --- a/.github/workflows/deploy-main.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Deploy from main branch - -on: - push: - branches: - - main - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - publish_image: - name: Publish Docker image - uses: './.github/workflows/publish-image.yml' - secrets: inherit - - deploy_main: - name: Deploy frontend - needs: publish_image - uses: blockscout/blockscout-ci-cd/.github/workflows/deploy_helmfile.yaml@master - with: - appName: front - globalEnv: main - helmfileDir: deploy - kubeConfigSecret: ci/data/dev/kubeconfig/k8s-dev - vaultRole: ci-dev - secrets: inherit - - deploy_l2: - name: Deploy frontend (L2) - needs: publish_image - uses: blockscout/blockscout-ci-cd/.github/workflows/deploy_helmfile.yaml@master - with: - appName: l2-optimism-goerli - globalEnv: optimism-goerli - helmfileDir: deploy - kubeConfigSecret: ci/data/dev/kubeconfig/k8s-dev - vaultRole: ci-dev - secrets: inherit diff --git a/.github/workflows/deploy-review-l2.yml b/.github/workflows/deploy-review-l2.yml deleted file mode 100644 index 02feb3ce64..0000000000 --- a/.github/workflows/deploy-review-l2.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Deploy review environment (L2) - -on: - workflow_dispatch: - -jobs: - make_slug: - name: Make GitHub reference slug - runs-on: ubuntu-latest - outputs: - REF_SLUG: ${{ steps.output.outputs.REF_SLUG }} - steps: - - name: Inject slug/short variables - uses: rlespinasse/github-slug-action@v4.4.1 - - - name: Set output - id: output - run: echo "REF_SLUG=${{ env.GITHUB_REF_NAME_SLUG }}" >> $GITHUB_OUTPUT - - publish_image: - name: Publish Docker image - needs: make_slug - uses: './.github/workflows/publish-image.yml' - with: - tags: ghcr.io/blockscout/frontend:review-${{ needs.make_slug.outputs.REF_SLUG }} - secrets: inherit - - deploy_review_l2: - name: Deploy frontend (L2) - needs: [ make_slug, publish_image ] - uses: blockscout/blockscout-ci-cd/.github/workflows/deploy_helmfile.yaml@master - with: - appName: review-l2-${{ needs.make_slug.outputs.REF_SLUG }} - globalEnv: review - helmfileDir: deploy - kubeConfigSecret: ci/data/dev/kubeconfig/k8s-dev - vaultRole: ci-dev - secrets: inherit diff --git a/.github/workflows/deploy-review.yml b/.github/workflows/deploy-review.yml deleted file mode 100644 index c5edbc8c50..0000000000 --- a/.github/workflows/deploy-review.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Deploy review environment - -on: - workflow_dispatch: - -jobs: - make_slug: - name: Make GitHub reference slug - runs-on: ubuntu-latest - outputs: - REF_SLUG: ${{ steps.output.outputs.REF_SLUG }} - steps: - - name: Inject slug/short variables - uses: rlespinasse/github-slug-action@v4.4.1 - - - name: Set output - id: output - run: echo "REF_SLUG=${{ env.GITHUB_REF_NAME_SLUG }}" >> $GITHUB_OUTPUT - - publish_image: - name: Publish Docker image - needs: make_slug - uses: './.github/workflows/publish-image.yml' - with: - tags: ghcr.io/blockscout/frontend:review-${{ needs.make_slug.outputs.REF_SLUG }} - secrets: inherit - - deploy_review: - name: Deploy frontend - needs: [ make_slug, publish_image ] - uses: blockscout/blockscout-ci-cd/.github/workflows/deploy_helmfile.yaml@master - with: - appName: review-${{ needs.make_slug.outputs.REF_SLUG }} - globalEnv: review - helmfileDir: deploy - kubeConfigSecret: ci/data/dev/kubeconfig/k8s-dev - vaultRole: ci-dev - secrets: inherit diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000000..2e3d86363d --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,23 @@ +name: Build and push Docker image + +on: + push: + branches: + - main + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: docker/setup-qemu-action@v1 + - uses: docker/setup-buildx-action@v1 + - uses: azure/docker-login@v1 + with: + login-server: ataacr.azurecr.io + username: ${{ secrets.ATA_ACR_USERNAME }} + password: ${{ secrets.ATA_ACR_PASSWORD }} + - uses: docker/build-push-action@v2 + with: + push: true + tags: ataacr.azurecr.io/blockscout-frontend:${{ github.sha }} diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml deleted file mode 100644 index 6aab1f48ff..0000000000 --- a/.github/workflows/e2e-tests.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Run E2E tests k8s - -on: - workflow_dispatch: - workflow_call: - -# concurrency: -# group: ${{ github.workflow }}__${{ github.job }}__${{ github.ref }} -# cancel-in-progress: true - -jobs: - publish_image: - name: Publish Docker image - uses: './.github/workflows/publish-image.yml' - secrets: inherit - - deploy_e2e: - name: Deploy E2E instance - needs: publish_image - runs-on: ubuntu-latest - permissions: write-all - steps: - - name: Get Vault credentials - id: retrieve-vault-secrets - uses: hashicorp/vault-action@v2.4.1 - with: - url: https://vault.k8s.blockscout.com - role: ci-dev - path: github-jwt - method: jwt - tlsSkipVerify: false - exportToken: true - secrets: | - ci/data/dev/github token | WORKFLOW_TRIGGER_TOKEN ; - - name: Trigger deploy - uses: convictional/trigger-workflow-and-wait@v1.6.1 - with: - owner: blockscout - repo: deployment-values - github_token: ${{ env.WORKFLOW_TRIGGER_TOKEN }} - workflow_file_name: deploy_blockscout.yaml - ref: main - wait_interval: 30 - client_payload: '{ "instance": "dev", "globalEnv": "e2e"}' - - test: - name: Run tests - needs: deploy_e2e - uses: blockscout/blockscout-ci-cd/.github/workflows/e2e_new.yaml@master - secrets: inherit \ No newline at end of file diff --git a/.github/workflows/label-issues-in-release.yml b/.github/workflows/label-issues-in-release.yml deleted file mode 100644 index 4bc9861b0d..0000000000 --- a/.github/workflows/label-issues-in-release.yml +++ /dev/null @@ -1,282 +0,0 @@ -name: Label issues in release - -on: - workflow_dispatch: - inputs: - tag: - description: 'Release tag' - required: true - type: string - label_name: - description: 'Name of the label' - required: true - type: string - label_description: - description: 'Description of the label' - default: '' - required: false - type: string - label_color: - description: 'A color of the added label' - default: 'FFFFFF' - required: false - type: string - workflow_call: - inputs: - tag: - description: 'Release tag' - required: true - type: string - label_name: - description: 'Name of the label' - required: true - type: string - label_description: - description: 'Description of the label' - default: '' - required: false - type: string - label_color: - description: 'A color of the added label' - default: 'FFFFFF' - required: false - type: string - outputs: - issues: - description: "JSON encoded list of issues linked to commits in the release" - value: ${{ jobs.run.outputs.issues }} - -# concurrency: -# group: ${{ github.workflow }}__${{ github.job }}__${{ github.ref }} -# cancel-in-progress: true - -jobs: - run: - name: Run - runs-on: ubuntu-latest - outputs: - issues: ${{ steps.linked_issues.outputs.result }} - steps: - - name: Getting tags of the two latestest releases - id: tags - uses: actions/github-script@v6 - env: - TAG: ${{ inputs.tag }} - with: - script: | - const { repository: { releases: { nodes: releases } } } = await github.graphql(` - query ($owner: String!, $repo: String!) { - repository(owner: $owner, name: $repo) { - releases(first: 10, orderBy: { field: CREATED_AT, direction: DESC }) { - nodes { - name - tagName - tagCommit { - oid - } - isPrerelease - isDraft - publishedAt - } - } - } - } - `, - { - owner: context.repo.owner, - repo: context.repo.repo, - } - ); - - if (releases[0].tagName !== process.env.TAG) { - core.info(`Current latest tag: ${ releases[0].tagName }`); - core.setFailed(`Release with tag ${ process.env.TAG } is not latest one.`); - return; - } - - const latestTag = process.env.TAG; - const [ { tagName: previousTag } ] = releases - .slice(1) - .filter(({ isDraft }) => !isDraft); - - core.info('Found following tags:'); - core.info(` latest: ${ latestTag }`); - core.info(` second latest: ${ previousTag }`); - - core.setOutput('latest', latestTag); - core.setOutput('previous', previousTag); - - - name: Looking for commits between two releases - id: commits - uses: actions/github-script@v6 - env: - PREVIOUS_TAG: ${{ steps.tags.outputs.previous }} - LATEST_TAG: ${{ steps.tags.outputs.latest }} - with: - script: | - const { data: { commits: commitsInRelease } } = await github.request('GET /repos/{owner}/{repo}/compare/{basehead}', { - owner: context.repo.owner, - repo: context.repo.repo, - basehead: `${ process.env.PREVIOUS_TAG }...${ process.env.LATEST_TAG }`, - }); - - if (commitsInRelease.length === 0) { - core.notice(`No commits found between ${ process.env.PREVIOUS_TAG } and ${ process.env.LATEST_TAG }`); - return []; - } - - const commits = commitsInRelease.map(({ sha }) => sha); - - core.startGroup(`Found ${ commits.length } commits`); - commits.forEach((sha) => { - core.info(sha); - }) - core.endGroup(); - - return commits; - - - name: Looking for issues linked to commits - id: linked_issues - uses: actions/github-script@v6 - env: - COMMITS: ${{ steps.commits.outputs.result }} - with: - script: | - const commits = JSON.parse(process.env.COMMITS); - - if (commits.length === 0) { - return []; - } - - const map = {}; - - core.startGroup(`Looking for linked issues`); - for (const sha of commits) { - const result = await getLinkedIssuesForCommitPR(sha); - result.forEach((issue) => { - map[issue] = issue; - }); - } - core.endGroup(); - - const issues = Object.values(map); - - if (issues.length > 0) { - core.startGroup(`Found ${ issues.length } unique issues`); - issues.sort().forEach((issue) => { - core.info(`#${ issue } - https://github.com/${ context.repo.owner }/${ context.repo.repo }/issues/${ issue }`); - }) - core.endGroup(); - } else { - core.notice('No linked issues found.'); - } - - return issues; - - async function getLinkedIssuesForCommitPR(sha) { - core.info(`Fetching issues for commit: ${ sha }`); - - const response = await github.graphql(` - query ($owner: String!, $repo: String!, $sha: GitObjectID!) { - repository(owner: $owner, name: $repo) { - object(oid: $sha) { - ... on Commit { - associatedPullRequests(first: 10) { - nodes { - number - title - state - merged - closingIssuesReferences(first: 10) { - nodes { - number - title - closed - } - } - } - } - } - } - } - } - `, { - owner: context.repo.owner, - repo: context.repo.repo, - sha, - }); - - if (!response) { - core.info('Nothing has found.'); - return []; - } - - const { repository: { object: { associatedPullRequests } } } = response; - - const issues = associatedPullRequests - .nodes - .map(({ closingIssuesReferences: { nodes: issues } }) => issues.map(({ number }) => number)) - .flat(); - - core.info(`Found following issues: ${ issues.join(', ') || '-' }\n`); - - return issues; - } - - - name: Creating label - id: label_creating - uses: actions/github-script@v6 - env: - LABEL_NAME: ${{ inputs.label_name }} - LABEL_COLOR: ${{ inputs.label_color }} - LABEL_DESCRIPTION: ${{ inputs.label_description }} - with: - script: | - try { - const result = await github.request('POST /repos/{owner}/{repo}/labels', { - owner: context.repo.owner, - repo: context.repo.repo, - name: process.env.LABEL_NAME, - color: process.env.LABEL_COLOR, - description: process.env.LABEL_DESCRIPTION, - }); - - core.info('Label was created.'); - } catch (error) { - if (error.status === 422) { - core.info('Label already exist.'); - } else { - core.setFailed(error.message); - } - } - - - - name: Adding label to issues - id: labeling_issues - uses: actions/github-script@v6 - env: - LABEL_NAME: ${{ inputs.label_name }} - ISSUES: ${{ steps.linked_issues.outputs.result }} - with: - script: | - const issues = JSON.parse(process.env.ISSUES); - - if (issues.length === 0) { - core.notice('No issues has found. Nothing to label.'); - return; - } - - for (const issue of issues) { - core.info(`Adding label to the issue #${ issue }...`); - await addLabelToIssue(issue, process.env.LABEL_NAME); - core.info('Done.\n'); - } - - async function addLabelToIssue(issue, label) { - return await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/labels', { - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issue, - labels: [ label ], - }); - } diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml deleted file mode 100644 index e0cb8684b8..0000000000 --- a/.github/workflows/pre-release.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Pre-release - -on: - workflow_dispatch: - push: - tags: - - 'v[0-9]+.[0-9]+.[0-9]+-[a-z]+*' # e.g v1.2.3-alpha.2 - -jobs: - checks: - name: Run code checks - uses: "./.github/workflows/checks.yml" - secrets: inherit - - # publish_image: - # image will be published in e2e-tests.yml workflow - # name: Publish Docker image - # uses: './.github/workflows/publish-image.yml' - # secrets: inherit - - e2e_tests: - name: Run e2e tests - needs: checks - uses: "./.github/workflows/e2e-tests.yml" - secrets: inherit - - version: - name: Pre-release version info - runs-on: ubuntu-latest - outputs: - is_initial: ${{ steps.is_initial.outputs.result }} - steps: - - name: Determine if it is the initial version of the pre-release - id: is_initial - uses: actions/github-script@v6 - env: - TAG: ${{ github.ref_name }} - with: - script: | - const tag = process.env.TAG; - const REGEXP = /^v[0-9]+.[0-9]+.[0-9]+-[a-z]+((\.|-)\d+)?$/i; - const match = tag.match(REGEXP); - const isInitial = match && !match[1] ? true : false; - core.info('is_initial flag value: ', isInitial); - return isInitial; - - label_issues: - name: Add pre-release label to issues - uses: './.github/workflows/label-issues-in-release.yml' - needs: [ version ] - if: ${{ needs.version.outputs.is_initial == 'true' }} - with: - tag: ${{ github.ref_name }} - label_name: 'pre-release' - label_description: Tasks in pre-release right now - secrets: inherit - - upload_source_maps: - name: Upload source maps to Sentry - uses: './.github/workflows/upload-source-maps.yml' - secrets: inherit diff --git a/.github/workflows/project-management.yml b/.github/workflows/project-management.yml deleted file mode 100644 index 791515b07d..0000000000 --- a/.github/workflows/project-management.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: Project management -on: - issues: - types: [ closed ] - pull_request: - types: [ review_requested ] - -jobs: - not_planned_issue: - name: Update task for not planned issue - if: ${{ github.event.issue && github.event.action == 'closed' && github.event.issue.state_reason == 'not_planned' }} - uses: './.github/workflows/update-project-cards.yml' - with: - project_name: ${{ vars.PROJECT_NAME }} - field_name: Status - field_value: Done - issues: "[${{ github.event.issue.number }}]" - secrets: inherit - - completed_issue: - name: Update task for completed issue - if: ${{ github.event.issue && github.event.action == 'closed' && github.event.issue.state_reason == 'completed' }} - uses: './.github/workflows/update-project-cards.yml' - with: - project_name: ${{ vars.PROJECT_NAME }} - field_name: Status - field_value: Ready For Realease - issues: "[${{ github.event.issue.number }}]" - secrets: inherit - - review_requested_issues: - name: Get issues linked to PR - runs-on: ubuntu-latest - if: ${{ github.event.pull_request && github.event.action == 'review_requested' }} - outputs: - issues: ${{ steps.linked_issues.outputs.result }} - steps: - - name: Fetching issues linked to pull request - id: linked_issues - uses: actions/github-script@v6 - env: - PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - with: - script: | - const response = await github.graphql(` - query ($owner: String!, $repo: String!, $pr: Int!) { - repository(owner: $owner, name: $repo) { - pullRequest(number: $pr) { - number - title - closingIssuesReferences(first: 100) { - nodes { - number - title - closed - } - } - } - } - } - `, { - owner: context.repo.owner, - repo: context.repo.repo, - pr: Number(process.env.PULL_REQUEST_NUMBER), - }); - - const { repository: { pullRequest: { closingIssuesReferences } } } = response; - const issues = closingIssuesReferences.nodes.map(({ number }) => number); - - if (!issues.length) { - core.notice(`No linked issues found for pull request #${ process.env.PULL_REQUEST_NUMBER }`); - return; - } - - core.info(`Found ${ issues.length } issue(s): ${ issues.join(', ') || '-' }`); - - return issues; - - review_requested_tasks: - name: Update status for issues in review - needs: [ review_requested_issues ] - if: ${{ needs.review_requested_issues.outputs.issues }} - uses: './.github/workflows/update-project-cards.yml' - secrets: inherit - with: - project_name: ${{ vars.PROJECT_NAME }} - field_name: Status - field_value: Review - issues: ${{ needs.review_requested_issues.outputs.issues }} diff --git a/.github/workflows/publish-image.yml b/.github/workflows/publish-image.yml deleted file mode 100644 index b1fdabff64..0000000000 --- a/.github/workflows/publish-image.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: Publish Docker image - -on: - workflow_dispatch: - inputs: - tags: - description: Image tags - required: false - type: string - workflow_call: - inputs: - tags: - description: Image tags - required: false - type: string - -jobs: - run: - name: Run - runs-on: ubuntu-latest - steps: - - name: Check out the repo - uses: actions/checkout@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - # Will automatically make nice tags, see the table here https://github.com/docker/metadata-action#basic - - name: Docker meta - id: meta - uses: docker/metadata-action@v4 - with: - images: ghcr.io/blockscout/frontend - - - name: Login to GitHub Container Registry - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Add SHORT_SHA env property with commit short sha - run: echo "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`" >> $GITHUB_ENV - - - name: Debug - env: - REF_TYPE: ${{ github.ref_type }} - REF_NAME: ${{ github.ref_name }} - run: | - echo "ref_type: $REF_TYPE" - echo "ref_name: $REF_NAME" - - - name: Build and push - uses: docker/build-push-action@v3 - with: - context: . - file: ./Dockerfile - push: true - cache-from: type=gha - tags: ${{ inputs.tags || steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: | - GIT_COMMIT_SHA=${{ env.SHORT_SHA }} - GIT_TAG=${{ github.ref_type == 'tag' && github.ref_name || '' }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index bbb3f07448..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Release - -on: - workflow_dispatch: - release: - types: [ released ] - -jobs: - remove_prerelease_label: - name: Remove pre-release label from issues - runs-on: ubuntu-latest - steps: - - name: Remove label - id: tags - uses: actions/github-script@v6 - env: - LABEL_NAME: pre-release - with: - script: | - const { data: issues } = await github.request('GET /repos/{owner}/{repo}/issues', { - owner: context.repo.owner, - repo: context.repo.repo, - labels: process.env.LABEL_NAME, - state: 'all' - }); - - if (issues.length === 0) { - core.notice(`No issues with label "${ process.env.LABEL_NAME }" found.`); - return; - } - - const issueIds = issues.map(({ node_id }) => node_id); - const labelId = issues[0].labels.find(({ name }) => name === process.env.LABEL_NAME).node_id; - - core.info(`Found ${ issueIds.length } issues with label "${ process.env.LABEL_NAME }"`); - - for (const issueId of issueIds) { - core.info(`Removing label for issue with node_id ${ issueId }...`); - - await github.graphql(` - mutation($input: RemoveLabelsFromLabelableInput!) { - removeLabelsFromLabelable(input: $input) { - clientMutationId - } - } - `, { - input: { - labelIds: [ labelId ], - labelableId: issueId - }, - }); - - core.info('Done.\n'); - } - - - label_released_issues: - name: Label released issues - uses: './.github/workflows/label-issues-in-release.yml' - with: - tag: ${{ github.ref_name }} - label_name: ${{ github.ref_name }} - label_description: Release ${{ github.ref_name }} - secrets: inherit - - update_project_cards: - name: Update project tasks statuses - needs: label_released_issues - uses: './.github/workflows/update-project-cards.yml' - with: - project_name: ${{ vars.PROJECT_NAME }} - field_name: Status - field_value: Released - issues: ${{ needs.label_released_issues.outputs.issues }} - secrets: inherit - - publish_image: - name: Publish Docker image - uses: './.github/workflows/publish-image.yml' - secrets: inherit - - upload_source_maps: - name: Upload source maps to Sentry - needs: publish_image - uses: './.github/workflows/upload-source-maps.yml' - secrets: inherit diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml deleted file mode 100644 index bcc1a36ca1..0000000000 --- a/.github/workflows/stale-issues.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Close inactive issues -on: - schedule: - - cron: "55 1 * * *" - -jobs: - close-issues: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: actions/stale@v5 - with: - # issues - only-issue-labels: "need info" - days-before-issue-stale: 14 - days-before-issue-close: 7 - stale-issue-label: "stale" - stale-issue-message: "This issue is stale because it has been open for 14 days with no activity." - close-issue-message: "This issue was closed because it has been inactive for 7 days since being marked as stale." - - # pull requests - days-before-pr-stale: -1 - days-before-pr-close: -1 - - # other settings - repo-token: ${{ secrets.GITHUB_TOKEN }} - close-issue-reason: "not_planned" \ No newline at end of file diff --git a/.github/workflows/update-project-cards.yml b/.github/workflows/update-project-cards.yml deleted file mode 100644 index 98ffbed2bb..0000000000 --- a/.github/workflows/update-project-cards.yml +++ /dev/null @@ -1,240 +0,0 @@ -name: Update project cards for issues - -on: - workflow_dispatch: - inputs: - project_name: - description: Name of the project - default: Front-end tasks - required: true - type: string - field_name: - description: Field name to be updated - default: Status - required: true - type: string - field_value: - description: New value of the field - default: Released - required: true - type: string - issues: - description: JSON encoded list of issue numbers to be updated - required: true - type: string - workflow_call: - inputs: - project_name: - description: Name of the project - required: true - type: string - field_name: - description: Field name to be updated - required: true - type: string - field_value: - description: New value of the field - required: true - type: string - issues: - description: JSON encoded list of issue numbers to be updated - required: true - type: string - -jobs: - run: - name: Run - runs-on: ubuntu-latest - steps: - - name: Getting project info - id: project_info - uses: actions/github-script@v6 - env: - PROJECT_NAME: ${{ inputs.project_name }} - FIELD_NAME: ${{ inputs.field_name }} - FIELD_VALUE: ${{ inputs.field_value }} - with: - github-token: ${{ secrets.BOT_LABEL_ISSUE_TOKEN }} - script: | - const response = await github.graphql(` - query ($login: String!, $q: String!) { - organization(login: $login) { - projectsV2(query: $q, first: 1) { - nodes { - id, - title, - number, - fields(first: 20) { - nodes { - ... on ProjectV2Field { - id - name - } - ... on ProjectV2SingleSelectField { - id - name - options { - id - name - } - } - } - } - } - } - } - } - `, { - login: context.repo.owner, - q: process.env.PROJECT_NAME, - }); - - const { organization: { projectsV2: { nodes: projects } } } = response; - - if (projects.length === 0) { - core.setFailed('Project not found.'); - return; - } - - if (projects.length > 1) { - core.info(`Fould ${ projects.length } with the similar name:`); - projects.forEach((issue) => { - core.info(` #${ projects.number } - ${ projects.title }`); - }) - core.setFailed('Fould multiple projects with the similar name. Cannot determine which one to use.'); - return; - } - - const { id: projectId, fields: { nodes: fields } } = projects[0]; - const field = fields.find((field) => field.name === process.env.FIELD_NAME); - - if (!field) { - core.setFailed(`Field with name "${ process.env.FIELD_NAME }" not found in the project.`); - return; - } - - const option = field.options.find((option) => option.name === process.env.FIELD_VALUE); - - if (!option) { - core.setFailed(`Option with name "${ process.env.FIELD_VALUE }" not found in the field possible values.`); - return; - } - - core.info('Found following info:'); - core.info(` project_id: ${ projectId }`); - core.info(` field_id: ${ field.id }`); - core.info(` field_value_id: ${ option.id }`); - - core.setOutput('id', projectId); - core.setOutput('field_id', field.id); - core.setOutput('field_value_id', option.id); - - - name: Getting project items that linked to the issues - id: items - uses: actions/github-script@v6 - env: - ISSUES: ${{ inputs.issues }} - with: - github-token: ${{ secrets.BOT_LABEL_ISSUE_TOKEN }} - script: | - const result = []; - const issues = JSON.parse(process.env.ISSUES); - - for (const issue of issues) { - const response = await getProjectItemId(issue); - response?.length > 0 && result.push(...response); - } - - return result; - - async function getProjectItemId(issueId) { - core.info(`Fetching project items for issue #${ issueId }...`); - - try { - const response = await github.graphql(` - query ($owner: String!, $repo: String!, $id: Int!) { - repository(owner: $owner, name: $repo) { - issue(number: $id) { - title, - projectItems(first: 10) { - nodes { - id, - } - } - } - } - } - `, - { - owner: context.repo.owner, - repo: context.repo.repo, - id: issueId, - } - ); - - const { repository: { issue: { projectItems: { nodes: projectItems } } } } = response; - - if (projectItems.length === 0) { - core.info('No project items found.\n'); - return []; - } - - const ids = projectItems.map((item) => item.id); - core.info(`Found [ ${ ids.join(', ') } ].\n`); - return ids; - - } catch (error) { - if (error.status === 404) { - core.info('Nothing has found.\n'); - return []; - } - } - } - - - name: Updating field value of the project items - id: updating_items - uses: actions/github-script@v6 - env: - ITEMS: ${{ steps.items.outputs.result }} - PROJECT_ID: ${{ steps.project_info.outputs.id }} - FIELD_ID: ${{ steps.project_info.outputs.field_id }} - FIELD_VALUE_ID: ${{ steps.project_info.outputs.field_value_id }} - with: - github-token: ${{ secrets.BOT_LABEL_ISSUE_TOKEN }} - script: | - const items = JSON.parse(process.env.ITEMS); - - if (items.length === 0) { - core.info('Nothing to update.'); - core.notice('No project items found for provided issues. Nothing to update.'); - return; - } - - for (const item of items) { - core.info(`Changing field value for item ${ item }...`); - await changeItemFieldValue(item); - core.info('Done.\n'); - } - - async function changeItemFieldValue(itemId) { - return await github.graphql( - ` - mutation($input: UpdateProjectV2ItemFieldValueInput!) { - updateProjectV2ItemFieldValue(input: $input) { - clientMutationId - } - } - `, - { - input: { - projectId: process.env.PROJECT_ID, - fieldId: process.env.FIELD_ID, - itemId, - value: { - singleSelectOptionId: process.env.FIELD_VALUE_ID, - }, - }, - } - ); - }; - diff --git a/.github/workflows/upload-source-maps.yml b/.github/workflows/upload-source-maps.yml deleted file mode 100644 index 0c284672a1..0000000000 --- a/.github/workflows/upload-source-maps.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Upload source maps to Sentry -on: - workflow_call: - workflow_dispatch: - -env: - SENTRY_ORG: ${{ vars.SENTRY_ORG }} - SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }} - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - SENTRY_DSN: ${{ secrets.SENTRY_DSN }} - -jobs: - build_and_upload: - name: Build app with source maps and upload to Sentry - runs-on: ubuntu-latest - if: ${{ github.ref_type == 'tag' }} - steps: - - name: Checkout repo - uses: actions/checkout@v3 - - - name: Setup node - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: 'yarn' - - - name: Cache node_modules - uses: actions/cache@v3 - id: cache-node-modules - with: - path: | - node_modules - key: node_modules-${{ runner.os }}-${{ hashFiles('yarn.lock') }} - - - name: Install dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: yarn --frozen-lockfile --ignore-optional - - - name: Make production build with source maps - run: yarn build - env: - NODE_ENV: production - - - name: Inject Sentry debug ID - run: yarn sentry-cli sourcemaps inject ./.next - - - name: Upload source maps to Sentry - run: yarn sentry-cli sourcemaps upload --release=${{ github.ref_name }} --url-prefix=~/_next/ --validate ./.next \ No newline at end of file diff --git a/pages/_document.tsx b/pages/_document.tsx index 74ebe08fb5..f70412709c 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -49,7 +49,11 @@ class MyDocument extends Document { - + diff --git a/public/icon.png b/public/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c2332399fe9833a6f03719d9a93519fe0db551af GIT binary patch literal 21588 zcmZ^~19WD=vo9J0RaJlmy#4!{#W|^dpv$Z{(CdVrlh!80{ z*_&C~n1X;vMy6^&X{wB21K=nFAgkKDe3)psxxspwSHHTuIuVcn-a|qqk27E2TCA@@ zJ_I0=tb?Z?K6(U$P$0dPo<>rjAfnjz{KbN_19f1w&~Qlmq0Bkuy-UnFHND=4?6>tc z5gQ;xl}_zRvLK7}LU~G~6CpTOzDPWgFT%(mXK)d|_jlyC#PY$bkn0h|X{Rg;{Ze2pZrS>{L{O1PJbiPXsR`m=GQlH4RmcyW}?v#R3JS^ z&HpMSS`K;%PGD#a$0|0H57kM)IBQCpceuq0s2R;&=_2tWYTlQE*k<`pa3ySz(>9# z=$#%YWyr@0vAUxx2=?8!@M{F#&5wOvBm}3uZdHD1)-c(_L)86za71T1Md^7VblHioNMiQYznb;SjE#9rUu+^WN_j^Miiox%dNn}}X+!L-`g zt+X^Tz@~5ZV8Xnx`M7;iA*un&FSKl+M8#TpJAC=5)2Fc?T73!P-)z3c`$qpK#I@rA z_78Iz8{!s1p5WZxX+w!R@!npoI`S%f9_j&+%JX_3S9q`J)RAOx*O2cUju#Wt%t`kO z=QGE*f)g4f+0^brQ12v#x|>#%L0I(zwNf5ru% z?y|Ol&<9%YBIxjK?LwS@U-z2-5R&`}pa1JE0@^5Y_1E-I)LXHjgrB4sQsVOovZ5i9 ziP)pOMR0&XRg&xkEfWT(pIm`CBHW4Equ@nQp0Pf{OseQh;<1V}E~Mk401Hl>_&5oc zxiJf5ZbIE4_1|nK@=c(8fqH_q`MM{tO@!bXFeTBMMhIA_#>PsTFlm8ObpTB&^|&R2 zM@<%=X^lGiD$Mr?R7dXVUi@7cgdtQ10)A{@D8n$#?WG6!c9?!2;jZrs2Ux6uWF3VE zGG|DAh-^QaFm!%SU8+NZ1I$&iT|W;=Vwp@6xmRy@hU_G{JOw>@&95tR0tz=2LgaTT z(j@+|yhD*F5=SYBB9wWpd3j~nQ|9vQhrlXfc4D67;4vx_2Kmrp}XeYGGmT$nX#`< zY~UI?d7MX_bDVcvbKF{HezQ$uVUAli z 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 literal 0 HcmV?d00001 diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..fa375686fc9d0354338fa07eeb784880141630e6 GIT binary patch literal 12331 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 literal 0 HcmV?d00001 diff --git a/theme/foundations/semanticTokens.ts b/theme/foundations/semanticTokens.ts index 27ccd9f2a3..59b8b448fd 100644 --- a/theme/foundations/semanticTokens.ts +++ b/theme/foundations/semanticTokens.ts @@ -17,7 +17,7 @@ const semanticTokens = { _dark: 'blue.300', }, link_hovered: { - 'default': 'blue.400', + 'default': '#e06612', }, error: { 'default': 'red.400', diff --git a/ui/home/StatsItem.tsx b/ui/home/StatsItem.tsx index eec90102c9..55b0872e8a 100644 --- a/ui/home/StatsItem.tsx +++ b/ui/home/StatsItem.tsx @@ -36,13 +36,14 @@ const StatsItem = ({ icon, title, value, className, tooltipLabel, url, isLoading [`@media screen and (min-width: ${ breakpoints.lg }) and (max-width: ${ LARGEST_BREAKPOINT })`]: { alignItems: 'center' }, }; - const bgColor = useColorModeValue('blue.50', 'blue.800'); + const bgColor = useColorModeValue('#fff', '#101112'); const loadingBgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50'); const infoColor = useColorModeValue('gray.600', 'gray.400'); return ( { const overlayRef = React.useRef(null); - const lineColor = useToken('colors', 'blue.500'); + const lineColor = '#FF6800'; const axesConfig = React.useMemo(() => { return { diff --git a/ui/home/indicators/ChainIndicators.tsx b/ui/home/indicators/ChainIndicators.tsx index d40148e763..60a5222757 100644 --- a/ui/home/indicators/ChainIndicators.tsx +++ b/ui/home/indicators/ChainIndicators.tsx @@ -62,6 +62,7 @@ const ChainIndicators = () => { borderRadius={{ base: 'none', lg: 'lg' }} boxShadow={{ base: 'none', lg: 'xl' }} bgColor={{ base: bgColorMobile, lg: bgColorDesktop }} + border="1px solid var(--chakra-colors-divider)" columnGap={ 12 } rowGap={ 0 } flexDir={{ base: 'column', lg: 'row' }} diff --git a/ui/shared/LinkInternal.tsx b/ui/shared/LinkInternal.tsx index b46b369096..74fda067b4 100644 --- a/ui/shared/LinkInternal.tsx +++ b/ui/shared/LinkInternal.tsx @@ -16,7 +16,7 @@ const LinkInternal = ({ isLoading, ...props }: LinkProps & { isLoading?: boolean return ( - + ); }; diff --git a/ui/shared/Tabs/TabsWithScroll.tsx b/ui/shared/Tabs/TabsWithScroll.tsx index f09644b675..4b1cd2c298 100644 --- a/ui/shared/Tabs/TabsWithScroll.tsx +++ b/ui/shared/Tabs/TabsWithScroll.tsx @@ -79,7 +79,7 @@ const TabsWithScroll = ({ { diff --git a/ui/shared/pagination/Pagination.tsx b/ui/shared/pagination/Pagination.tsx index 67c2c0593d..6956395420 100644 --- a/ui/shared/pagination/Pagination.tsx +++ b/ui/shared/pagination/Pagination.tsx @@ -25,6 +25,7 @@ const Pagination = ({ page, onNextPageClick, onPrevPageClick, resetPage, hasPage >