mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
Delete the workflows the forge never reads
git.hanzo.ai resolves .hanzo/workflows and stops there, so these ran on no push and reported green on every one. CI is native and lives in .hanzo/workflows.
This commit is contained in:
@@ -1,432 +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
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
code_quality:
|
||||
name: Code quality
|
||||
runs-on: lux-build-amd64
|
||||
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@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.14.0
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
key: node_modules-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Generate Chakra types
|
||||
if: steps.cache-node-modules.outputs.cache-hit == 'true'
|
||||
run: pnpm chakra:typegen
|
||||
|
||||
- name: Run ESLint
|
||||
run: pnpm lint:eslint
|
||||
|
||||
- name: Compile TypeScript
|
||||
run: pnpm lint:tsc
|
||||
|
||||
- name: Check licenses
|
||||
run: pnpm lint:license:check
|
||||
|
||||
- name: Check spelling
|
||||
run: pnpm lint:cspell --no-progress
|
||||
|
||||
toolkit_build_check:
|
||||
name: Toolkit build check
|
||||
needs: [ code_quality ]
|
||||
runs-on: lux-build-amd64
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.14.0
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
key: node_modules-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install project dependencies
|
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Generate Chakra types
|
||||
if: steps.cache-node-modules.outputs.cache-hit == 'true'
|
||||
run: pnpm chakra:typegen
|
||||
|
||||
- name: Install package dependencies
|
||||
run: |
|
||||
cd ./toolkit/package
|
||||
pnpm install --no-lockfile
|
||||
|
||||
- name: Type check the package
|
||||
run: |
|
||||
cd ./toolkit/package
|
||||
pnpm typecheck
|
||||
|
||||
- name: Build the package
|
||||
run: |
|
||||
cd ./toolkit/package
|
||||
pnpm build
|
||||
|
||||
- name: Verify build output
|
||||
run: |
|
||||
cd ./toolkit/package
|
||||
if [ ! -d "dist" ]; then
|
||||
echo "Build failed: dist directory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "dist/index.js" ]; then
|
||||
echo "Build failed: dist/index.js not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "dist/index.d.ts" ]; then
|
||||
echo "Build failed: dist/index.d.ts not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
envs_validation:
|
||||
name: ENV variables validation
|
||||
runs-on: lux-build-amd64
|
||||
needs: [ code_quality ]
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.14.0
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
key: node_modules-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Generate Chakra types
|
||||
if: steps.cache-node-modules.outputs.cache-hit == 'true'
|
||||
run: pnpm chakra:typegen
|
||||
|
||||
- name: Install script dependencies
|
||||
run: cd ./deploy/tools/envs-validator && pnpm install --no-lockfile
|
||||
|
||||
- name: Run validation tests
|
||||
run: |
|
||||
set +e
|
||||
cd ./deploy/tools/envs-validator && pnpm test
|
||||
exitcode="$?"
|
||||
echo "exitcode=$exitcode" >> $GITHUB_OUTPUT
|
||||
exit "$exitcode"
|
||||
|
||||
vitest_tests:
|
||||
name: Unit tests
|
||||
needs: [ code_quality, envs_validation ]
|
||||
runs-on: lux-build-amd64
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.14.0
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
key: node_modules-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Generate Chakra types
|
||||
if: steps.cache-node-modules.outputs.cache-hit == 'true'
|
||||
run: pnpm chakra:typegen
|
||||
|
||||
- name: Run Vitest
|
||||
run: pnpm test:vitest ${{ github.event_name == 'pull_request' && '--changed=origin/main' || '' }} --passWithNoTests
|
||||
|
||||
pw_affected_tests:
|
||||
name: Resolve affected Playwright tests
|
||||
runs-on: lux-build-amd64
|
||||
needs: [ code_quality, envs_validation ]
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.14.0
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
key: node_modules-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Generate Chakra types
|
||||
if: steps.cache-node-modules.outputs.cache-hit == 'true'
|
||||
run: pnpm chakra:typegen
|
||||
|
||||
- name: Install script dependencies
|
||||
run: cd ./deploy/tools/affected-tests && pnpm install --no-lockfile
|
||||
|
||||
- name: Run script
|
||||
run: pnpm test:pw:detect-affected
|
||||
|
||||
- name: Upload result file
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: playwright-affected-tests
|
||||
path: ./playwright/affected-tests.txt
|
||||
retention-days: 3
|
||||
|
||||
pw_tests:
|
||||
name: 'Playwright tests / Project: ${{ matrix.project }}'
|
||||
needs: [ code_quality, envs_validation, pw_affected_tests ]
|
||||
if: |
|
||||
always() &&
|
||||
needs.code_quality.result == 'success' &&
|
||||
needs.envs_validation.result == 'success' &&
|
||||
(needs.pw_affected_tests.result == 'success' || needs.pw_affected_tests.result == 'skipped')
|
||||
runs-on: lux-build-amd64
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.57.0-noble
|
||||
|
||||
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@v4
|
||||
with:
|
||||
lfs: 'true'
|
||||
|
||||
- name: Setup pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.14.0
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
key: node_modules-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Generate Chakra types
|
||||
if: steps.cache-node-modules.outputs.cache-hit == 'true'
|
||||
run: pnpm chakra:typegen
|
||||
|
||||
- name: Download affected tests list
|
||||
if: ${{ needs.pw_affected_tests.result == 'success' }}
|
||||
uses: actions/download-artifact@v5
|
||||
continue-on-error: true
|
||||
with:
|
||||
name: playwright-affected-tests
|
||||
path: ./playwright
|
||||
|
||||
- name: Run PlayWright
|
||||
run: pnpm test:pw:ci --affected=${{ github.event_name == 'pull_request' }} --pass-with-no-tests
|
||||
env:
|
||||
HOME: /root
|
||||
PW_PROJECT: ${{ matrix.project }}
|
||||
|
||||
- name: Upload blob report to GitHub Actions Artifacts
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: blob-report-${{ matrix.project }}
|
||||
path: blob-report
|
||||
retention-days: 1
|
||||
|
||||
pw_report:
|
||||
name: Generate Playwright report
|
||||
# Merge reports after pw_tests job, even if some shards have failed
|
||||
if: ${{ !cancelled() }}
|
||||
runs-on: lux-build-amd64
|
||||
needs: [ pw_tests ]
|
||||
steps:
|
||||
- name: Download blob reports from GitHub Actions Artifacts
|
||||
id: download-reports
|
||||
uses: actions/download-artifact@v5
|
||||
continue-on-error: true
|
||||
with:
|
||||
path: ${{ runner.temp }}/all-blob-reports
|
||||
pattern: blob-report-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Check for downloaded reports
|
||||
id: check-reports
|
||||
run: |
|
||||
if [ -d "$RUNNER_TEMP/all-blob-reports" ] && [ -n "$(ls -A "$RUNNER_TEMP/all-blob-reports" 2>/dev/null)" ]; then
|
||||
echo "has_reports=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "has_reports=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Checkout repo
|
||||
if: steps.check-reports.outputs.has_reports == 'true'
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup pnpm
|
||||
if: steps.check-reports.outputs.has_reports == 'true'
|
||||
uses: pnpm/action-setup@v4
|
||||
|
||||
- name: Setup node
|
||||
if: steps.check-reports.outputs.has_reports == 'true'
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22.14.0
|
||||
cache: 'pnpm'
|
||||
|
||||
- name: Cache node_modules
|
||||
if: steps.check-reports.outputs.has_reports == 'true'
|
||||
uses: actions/cache@v4
|
||||
id: cache-node-modules
|
||||
with:
|
||||
path: |
|
||||
node_modules
|
||||
key: node_modules-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.check-reports.outputs.has_reports == 'true' && steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Merge into HTML Report
|
||||
if: steps.check-reports.outputs.has_reports == 'true'
|
||||
run: npx playwright merge-reports --reporter html "$RUNNER_TEMP/all-blob-reports"
|
||||
|
||||
- name: Upload HTML report artifact
|
||||
# Upload HTML report to GitHub Actions Artifacts only for pull requests from forks
|
||||
if: steps.check-reports.outputs.has_reports == 'true' && (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: playwright-html-report
|
||||
path: playwright-report
|
||||
retention-days: 7
|
||||
|
||||
- name: Configure AWS credentials
|
||||
if: steps.check-reports.outputs.has_reports == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws-region: ${{ vars.AWS_REGION }}
|
||||
|
||||
- name: Upload HTML report to S3
|
||||
# Upload HTML report to S3 only for pull requests from the main repository or for non-pull requests events
|
||||
if: steps.check-reports.outputs.has_reports == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository)
|
||||
run: |
|
||||
export "SHORT_SHA=`echo ${GITHUB_SHA} | cut -c1-8`"
|
||||
aws s3 cp playwright-report/ s3://${{ vars.AWS_BUCKET_NAME }}/report-${SHORT_SHA} --recursive
|
||||
echo "PLAYWRIGHT_URL=https://${{ vars.AWS_BUCKET_NAME }}.s3.${{ vars.AWS_REGION }}.amazonaws.com/report-${SHORT_SHA}/index.html" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Add link to job summary
|
||||
if: steps.check-reports.outputs.has_reports == 'true'
|
||||
run: |
|
||||
echo "### Playwright report" >> $GITHUB_STEP_SUMMARY
|
||||
if [ -n "${{ env.PLAYWRIGHT_URL }}" ]; then
|
||||
echo "[View report (S3)](${{ env.PLAYWRIGHT_URL }})" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "Download the **playwright-html-report** artifact below to view the report (open \`index.html\` in a browser)." >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "[Read about ducks](https://animalkingdom.org/animals/ducks/)" >> $GITHUB_STEP_SUMMARY
|
||||
@@ -1,38 +0,0 @@
|
||||
name: Cleanup environments
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
- merged
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
cleanup_release:
|
||||
uses: blockscout/actions/.github/workflows/cleanup_helmfile.yaml@main
|
||||
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/actions/.github/workflows/cleanup_helmfile.yaml@main
|
||||
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/actions/.github/workflows/cleanup_docker.yaml@main
|
||||
with:
|
||||
dockerImage: review-$GITHUB_REF_NAME_SLUG
|
||||
secrets: inherit
|
||||
@@ -1,122 +0,0 @@
|
||||
name: Copy issues labels to pull request
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pr_number:
|
||||
description: Pull request number
|
||||
required: true
|
||||
type: string
|
||||
issues:
|
||||
description: JSON encoded list of issue ids
|
||||
required: true
|
||||
type: string
|
||||
workflow_call:
|
||||
inputs:
|
||||
pr_number:
|
||||
description: Pull request number
|
||||
required: true
|
||||
type: string
|
||||
issues:
|
||||
description: JSON encoded list of issue ids
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
issues: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: Run
|
||||
runs-on: lux-build-amd64
|
||||
steps:
|
||||
- name: Find unique labels
|
||||
id: find_unique_labels
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
ISSUES: ${{ inputs.issues }}
|
||||
with:
|
||||
script: |
|
||||
const issues = JSON.parse(process.env.ISSUES);
|
||||
|
||||
const WHITE_LISTED_LABELS = [
|
||||
'client feature',
|
||||
'feature',
|
||||
'breaking changes',
|
||||
|
||||
'bug',
|
||||
|
||||
'dependencies',
|
||||
'performance',
|
||||
'design',
|
||||
|
||||
'chore',
|
||||
'enhancement',
|
||||
'refactoring',
|
||||
'tech',
|
||||
'ENVs',
|
||||
]
|
||||
|
||||
const labels = await Promise.all(issues.map(getIssueLabels));
|
||||
const uniqueLabels = uniqueStringArray(labels.flat().filter((label) => WHITE_LISTED_LABELS.includes(label)));
|
||||
|
||||
if (uniqueLabels.length === 0) {
|
||||
core.info('No labels found.\n');
|
||||
return [];
|
||||
}
|
||||
|
||||
core.info(`Found following labels: ${ uniqueLabels.join(', ') }.\n`);
|
||||
return uniqueLabels;
|
||||
|
||||
async function getIssueLabels(issue) {
|
||||
core.info(`Obtaining labels list for the issue #${ issue }...`);
|
||||
|
||||
try {
|
||||
const response = await github.request('GET /repos/{owner}/{repo}/issues/{issue_number}/labels', {
|
||||
owner: 'blockscout',
|
||||
repo: 'frontend',
|
||||
issue_number: issue,
|
||||
});
|
||||
return response.data.map(({ name }) => name);
|
||||
} catch (error) {
|
||||
core.error(`Failed to obtain labels for the issue #${ issue }: ${ error.message }`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function uniqueStringArray(array) {
|
||||
return Array.from(new Set(array));
|
||||
}
|
||||
|
||||
- name: Update pull request labels
|
||||
id: update_pr_labels
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
LABELS: ${{ steps.find_unique_labels.outputs.result }}
|
||||
PR_NUMBER: ${{ inputs.pr_number }}
|
||||
with:
|
||||
script: |
|
||||
const labels = JSON.parse(process.env.LABELS);
|
||||
const prNumber = Number(process.env.PR_NUMBER);
|
||||
|
||||
if (labels.length === 0) {
|
||||
core.info('Nothing to update.\n');
|
||||
return;
|
||||
}
|
||||
|
||||
for (const label of labels) {
|
||||
await addLabelToPr(prNumber, label);
|
||||
}
|
||||
core.info('Done.\n');
|
||||
|
||||
async function addLabelToPr(prNumber, label) {
|
||||
console.log(`Adding label to the pull request #${ prNumber }...`);
|
||||
|
||||
return await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/labels', {
|
||||
owner: 'blockscout',
|
||||
repo: 'frontend',
|
||||
issue_number: prNumber,
|
||||
labels: [ label ],
|
||||
});
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
name: Deploy from main branch
|
||||
|
||||
on:
|
||||
# NOTE: Currently disabled to avoid unnecessary deployments since we only publish private images and do not use unstable builds in our internal pipelines.
|
||||
# push:
|
||||
# branches:
|
||||
# - main
|
||||
# paths-ignore:
|
||||
# - '.github/ISSUE_TEMPLATE/**'
|
||||
# - '.husky/**'
|
||||
# - '.vscode/**'
|
||||
# - 'docs/**'
|
||||
# - 'vitest/**'
|
||||
# - 'mocks/**'
|
||||
# - 'playwright/**'
|
||||
# - 'stubs/**'
|
||||
# - 'tools/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
publish_image:
|
||||
name: Publish Docker image
|
||||
uses: './.github/workflows/publish-image.yml'
|
||||
secrets: inherit
|
||||
with:
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=raw,value=unstable
|
||||
platforms: linux/amd64
|
||||
@@ -1,85 +0,0 @@
|
||||
name: Deploy review environment (L2)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
envs_preset:
|
||||
description: ENVs preset
|
||||
required: false
|
||||
default: ""
|
||||
type: choice
|
||||
options:
|
||||
- none
|
||||
- arbitrum
|
||||
- arbitrum_nova
|
||||
- arbitrum_sepolia
|
||||
- base
|
||||
- celo
|
||||
- celo_sepolia
|
||||
- garnet
|
||||
- gnosis
|
||||
- eth
|
||||
- eth_sepolia
|
||||
- filecoin
|
||||
- immutable
|
||||
- mega_eth
|
||||
- multichain_dev
|
||||
- multichain_prod
|
||||
- neon_devnet
|
||||
- numine
|
||||
- optimism
|
||||
- optimism_sepolia
|
||||
- polygon
|
||||
- rootstock
|
||||
- scroll_sepolia
|
||||
- shibarium
|
||||
- stability
|
||||
- zetachain
|
||||
- zetachain_testnet
|
||||
- zkevm
|
||||
- zilliqa
|
||||
- zksync
|
||||
- zora
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
make_slug:
|
||||
name: Make GitHub reference slug
|
||||
runs-on: lux-build-amd64
|
||||
outputs:
|
||||
REF_SLUG: ${{ steps.output.outputs.REF_SLUG }}
|
||||
steps:
|
||||
- name: Inject slug/short variables
|
||||
uses: rlespinasse/[email protected]
|
||||
|
||||
- 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: |
|
||||
type=raw,value=review-${{ needs.make_slug.outputs.REF_SLUG }}
|
||||
build_args: ENVS_PRESET=${{ inputs.envs_preset }}
|
||||
platforms: linux/amd64
|
||||
secrets: inherit
|
||||
|
||||
deploy_review_l2:
|
||||
name: Deploy frontend (L2)
|
||||
needs: [ make_slug, publish_image ]
|
||||
uses: blockscout/actions/.github/workflows/deploy_helmfile.yaml@main
|
||||
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
|
||||
permissions: write-all
|
||||
@@ -1,90 +0,0 @@
|
||||
name: Deploy review environment
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
envs_preset:
|
||||
description: ENVs preset
|
||||
required: false
|
||||
default: main
|
||||
type: choice
|
||||
options:
|
||||
- none
|
||||
- arbitrum
|
||||
- arbitrum_nova
|
||||
- arbitrum_sepolia
|
||||
- base
|
||||
- celo
|
||||
- celo_sepolia
|
||||
- garnet
|
||||
- gnosis
|
||||
- eth
|
||||
- eth_sepolia
|
||||
- filecoin
|
||||
- immutable
|
||||
- main
|
||||
- mega_eth
|
||||
- mekong
|
||||
- multichain_dev
|
||||
- multichain_prod
|
||||
- neon_devnet
|
||||
- numine
|
||||
- optimism
|
||||
- optimism_sepolia
|
||||
- polygon
|
||||
- rari_testnet
|
||||
- rootstock
|
||||
- shibarium
|
||||
- scroll_sepolia
|
||||
- stability
|
||||
- tac
|
||||
- tac_spb
|
||||
- zetachain
|
||||
- zetachain_testnet
|
||||
- zkevm
|
||||
- zilliqa
|
||||
- zksync
|
||||
- zora
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
make_slug:
|
||||
name: Make GitHub reference slug
|
||||
runs-on: lux-build-amd64
|
||||
outputs:
|
||||
REF_SLUG: ${{ steps.output.outputs.REF_SLUG }}
|
||||
steps:
|
||||
- name: Inject slug/short variables
|
||||
uses: rlespinasse/[email protected]
|
||||
|
||||
- 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: |
|
||||
type=raw,value=review-${{ needs.make_slug.outputs.REF_SLUG }}
|
||||
build_args: ENVS_PRESET=${{ inputs.envs_preset }}
|
||||
platforms: linux/amd64
|
||||
secrets: inherit
|
||||
|
||||
deploy_review:
|
||||
name: Deploy frontend
|
||||
needs: [ make_slug, publish_image ]
|
||||
uses: blockscout/actions/.github/workflows/deploy_helmfile.yaml@main
|
||||
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
|
||||
permissions: write-all
|
||||
@@ -1,81 +0,0 @@
|
||||
name: Run E2E tests k8s
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_call:
|
||||
|
||||
# concurrency:
|
||||
# group: ${{ github.workflow }}__${{ github.job }}__${{ github.ref }}
|
||||
# cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
publish_image:
|
||||
name: Publish Docker image
|
||||
uses: './.github/workflows/publish-image.yml'
|
||||
secrets: inherit
|
||||
with:
|
||||
# NOTE: by default the image will be built with type=ref,event=tag; so we don't need to specify it here
|
||||
tags: |
|
||||
type=raw,value=e2e
|
||||
platforms: linux/amd64
|
||||
|
||||
deploy_e2e:
|
||||
name: Deploy E2E instance
|
||||
needs: publish_image
|
||||
runs-on: lux-build-amd64
|
||||
permissions: write-all
|
||||
steps:
|
||||
- name: Get Vault credentials
|
||||
id: retrieve-vault-secrets
|
||||
uses: hashicorp/[email protected]
|
||||
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/[email protected]
|
||||
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
|
||||
runs-on: lux-build-amd64
|
||||
permissions: write-all
|
||||
steps:
|
||||
- name: Get Vault credentials
|
||||
id: retrieve-vault-secrets
|
||||
uses: hashicorp/[email protected]
|
||||
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 tests
|
||||
uses: convictional/[email protected]
|
||||
with:
|
||||
owner: blockscout
|
||||
repo: blockscout-ci-cd
|
||||
github_token: ${{ env.WORKFLOW_TRIGGER_TOKEN }}
|
||||
workflow_file_name: e2e_new.yaml
|
||||
ref: master
|
||||
wait_interval: 30
|
||||
@@ -1,291 +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
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: Run
|
||||
runs-on: lux-build-amd64
|
||||
outputs:
|
||||
issues: ${{ steps.linked_issues.outputs.result }}
|
||||
steps:
|
||||
- name: Getting tags of the two latest releases
|
||||
id: tags
|
||||
uses: actions/github-script@v7
|
||||
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@v7
|
||||
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@v7
|
||||
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
|
||||
labels(first: 5) {
|
||||
nodes {
|
||||
description
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`, {
|
||||
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
|
||||
.filter(({ closingIssuesReferences: { nodes: issues } }) => !issues?.some(({ labels }) => labels?.nodes?.some(({ description }) => description?.toLowerCase().startsWith('release'))))
|
||||
.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@v7
|
||||
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@v7
|
||||
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 ],
|
||||
});
|
||||
}
|
||||
@@ -1,67 +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
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
publish_image:
|
||||
name: Publish Docker image
|
||||
uses: './.github/workflows/publish-image.yml'
|
||||
secrets: inherit
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
|
||||
# e2e_tests:
|
||||
# decided to disable e2e temporarily
|
||||
# name: Run e2e tests
|
||||
# needs: checks
|
||||
# uses: "./.github/workflows/e2e-tests.yml"
|
||||
# secrets: inherit
|
||||
# permissions: write-all
|
||||
|
||||
version:
|
||||
name: Pre-release version info
|
||||
runs-on: lux-build-amd64
|
||||
permissions:
|
||||
contents: read
|
||||
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@v7
|
||||
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
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
@@ -1,111 +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
|
||||
permissions:
|
||||
issues: read
|
||||
|
||||
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 Release
|
||||
issues: "[${{ github.event.issue.number }}]"
|
||||
secrets: inherit
|
||||
permissions:
|
||||
issues: read
|
||||
|
||||
pr_linked_issues:
|
||||
name: Get issues linked to PR
|
||||
runs-on: lux-build-amd64
|
||||
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@v7
|
||||
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;
|
||||
permissions:
|
||||
issues: read
|
||||
pull-requests: read
|
||||
|
||||
issues_in_review:
|
||||
name: Update status for issues in review
|
||||
needs: [ pr_linked_issues ]
|
||||
if: ${{ needs.pr_linked_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.pr_linked_issues.outputs.issues }}
|
||||
permissions:
|
||||
issues: read
|
||||
|
||||
copy_labels:
|
||||
name: Copy issues labels to pull request
|
||||
needs: [ pr_linked_issues ]
|
||||
if: ${{ needs.pr_linked_issues.outputs.issues }}
|
||||
uses: './.github/workflows/copy-issues-labels.yml'
|
||||
secrets: inherit
|
||||
with:
|
||||
pr_number: ${{ github.event.pull_request.number }}
|
||||
issues: ${{ needs.pr_linked_issues.outputs.issues }}
|
||||
permissions:
|
||||
issues: read
|
||||
pull-requests: write
|
||||
@@ -1,113 +0,0 @@
|
||||
name: Publish Docker image
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tags:
|
||||
description: Image tags (e.g. "type=raw,value=foo")
|
||||
required: false
|
||||
type: string
|
||||
build_args:
|
||||
description: Build-time variables
|
||||
required: false
|
||||
type: string
|
||||
platforms:
|
||||
description: Image platforms (you can specify multiple platforms separated by comma)
|
||||
required: false
|
||||
type: string
|
||||
default: linux/amd64,linux/arm64/v8
|
||||
private:
|
||||
description: Make image private (true) or public (false)
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
workflow_call:
|
||||
inputs:
|
||||
tags:
|
||||
description: Image tags (e.g. "type=raw,value=foo")
|
||||
required: false
|
||||
type: string
|
||||
build_args:
|
||||
description: Build-time variables
|
||||
required: false
|
||||
type: string
|
||||
platforms:
|
||||
description: Image platforms (you can specify multiple platforms separated by comma)
|
||||
required: false
|
||||
type: string
|
||||
default: linux/amd64,linux/arm64/v8
|
||||
private:
|
||||
description: Make image private (true) or public (false)
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: Run
|
||||
runs-on: lux-build-amd64
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set image name based on private flag
|
||||
id: image-name
|
||||
run: |
|
||||
echo "image-name=ghcr.io/luxfi/explore" >> $GITHUB_OUTPUT
|
||||
|
||||
# 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@v5
|
||||
with:
|
||||
images: ${{ steps.image-name.outputs.image-name }}
|
||||
flavor: |
|
||||
latest=false
|
||||
tags: |
|
||||
type=ref,event=tag
|
||||
${{ inputs.tags }}
|
||||
|
||||
- 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 }}
|
||||
IMAGE_NAME: ${{ steps.image-name.outputs.image-name }}
|
||||
IS_PRIVATE: ${{ inputs.private }}
|
||||
run: |
|
||||
echo "ref_type: $REF_TYPE"
|
||||
echo "ref_name: $REF_NAME"
|
||||
echo "image_name: $IMAGE_NAME"
|
||||
echo "is_private: $IS_PRIVATE"
|
||||
|
||||
- name: Setup repo
|
||||
uses: blockscout/actions/.github/actions/setup-multiarch-buildx@no-metadata
|
||||
id: setup
|
||||
with:
|
||||
docker-image: ${{ steps.image-name.outputs.image-name }}
|
||||
docker-username: ${{ github.actor }}
|
||||
docker-password: ${{ secrets.GITHUB_TOKEN }}
|
||||
docker-remote-multi-platform: true
|
||||
docker-arm-host: ${{ secrets.ARM_RUNNER_HOSTNAME }}
|
||||
docker-arm-host-key: ${{ secrets.ARM_RUNNER_KEY }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
platforms: ${{ inputs.platforms }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
GIT_COMMIT_SHA=${{ env.SHORT_SHA }}
|
||||
GIT_TAG=${{ github.ref_type == 'tag' && github.ref_name || '' }}
|
||||
${{ inputs.build_args }}
|
||||
@@ -1,104 +0,0 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [ released ]
|
||||
|
||||
jobs:
|
||||
remove_prerelease_label:
|
||||
name: Remove pre-release label from issues
|
||||
runs-on: lux-build-amd64
|
||||
steps:
|
||||
- name: Remove label
|
||||
id: tags
|
||||
uses: actions/github-script@v7
|
||||
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');
|
||||
}
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
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
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
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
|
||||
permissions:
|
||||
issues: read
|
||||
|
||||
publish_image:
|
||||
name: Publish Docker image
|
||||
uses: './.github/workflows/publish-image.yml'
|
||||
secrets: inherit
|
||||
with:
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
# NOTE: by default the image will be built with type=ref,event=tag; so we need to specify it here
|
||||
tags: |
|
||||
type=raw,value=latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
publish_toolkit:
|
||||
name: Publish toolkit package to NPM
|
||||
uses: './.github/workflows/toolkit-npm-publisher.yml'
|
||||
secrets: inherit
|
||||
with:
|
||||
version: ${{ github.ref_name }}
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
@@ -1,29 +0,0 @@
|
||||
name: Close inactive issues
|
||||
on:
|
||||
schedule:
|
||||
- cron: "55 1 * * *"
|
||||
|
||||
jobs:
|
||||
close-issues:
|
||||
runs-on: lux-build-amd64
|
||||
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"
|
||||
@@ -1,67 +0,0 @@
|
||||
name: Publish toolkit package to NPM
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: Package version
|
||||
type: string
|
||||
required: true
|
||||
workflow_call:
|
||||
inputs:
|
||||
version:
|
||||
description: Package version
|
||||
type: string
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: lux-build-amd64
|
||||
name: Publish package to NPM registry
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Also it will setup .npmrc file to publish to npm
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22.14.0'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
# Ensure npm 11.5.1 is installed
|
||||
- name: Update npm
|
||||
run: npm install -g [email protected]
|
||||
|
||||
- name: Update package version
|
||||
run: |
|
||||
cd ./toolkit/package
|
||||
npm version ${{ inputs.version }}
|
||||
|
||||
- name: Setup pnpm
|
||||
run: corepack enable && corepack prepare [email protected] --activate
|
||||
|
||||
- name: Build the package
|
||||
run: |
|
||||
pnpm install --frozen-lockfile
|
||||
cd ./toolkit/package
|
||||
pnpm install --no-lockfile
|
||||
pnpm build
|
||||
|
||||
- name: Publish to NPM registry
|
||||
run: |
|
||||
cd ./toolkit/package
|
||||
# Determine npm tag based on version
|
||||
if [[ "${{ inputs.version }}" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
# Stable release (e.g., 1.7.2 or v1.7.2)
|
||||
npm publish --access public --tag latest
|
||||
else
|
||||
# Pre-release (e.g., 1.7.2-alpha.1 or v1.7.2-alpha.1)
|
||||
npm publish --access public --tag beta
|
||||
fi
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -1,248 +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
|
||||
|
||||
permissions:
|
||||
issues: read
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: Run
|
||||
runs-on: lux-build-amd64
|
||||
steps:
|
||||
- name: Getting project info
|
||||
id: project_info
|
||||
uses: actions/github-script@v7
|
||||
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(`Found ${ projects.length } with the similar name:`);
|
||||
projects.forEach((issue) => {
|
||||
core.info(` #${ projects.number } - ${ projects.title }`);
|
||||
})
|
||||
core.setFailed('Found 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@v7
|
||||
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');
|
||||
}
|
||||
core.info(`Error: ${ error.message }\n`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
- name: Updating field value of the project items
|
||||
id: updating_items
|
||||
uses: actions/github-script@v7
|
||||
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 }...`);
|
||||
try {
|
||||
await changeItemFieldValue(item);
|
||||
core.info('Done.\n');
|
||||
} catch (error) {
|
||||
core.info(`Error: ${ error.message }\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,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user