Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/update_neuron_compatible.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Update Neuron compatibility table

on:
push:
branches:
- 'rc/**'
paths:
- 'package.json'

jobs:
update-neuron-compatible:
name: Update Neuron compatibility table
runs-on: ubuntu-latest
permissions:
pull-requests: write # open PR
contents: write # update version files

steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 20.x

- name: Update versions
id: update_versions
run: |
npm run update:neuron-compatible
git add compatible.json

- name: Set GPG
if: ${{ success() }}
uses: crazy-max/ghaction-import-gpg@v5
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
git_user_signingkey: true
git_commit_gpgsign: true

- name: Open PR to RC branch
if: ${{ success() }}
uses: peter-evans/create-pull-request@v5
with:
title: Update Neuron compatibility table
commit-message: 'feat: Update Neuron compatibility table'
body: 'Update Neuron compatibility table for a new release'
committer: Chen Yu <chenyu@magickbase.com>
branch: update-neuron-compatible
base: ${{ github.ref_name }}
6 changes: 0 additions & 6 deletions compatible.csv

This file was deleted.

57 changes: 57 additions & 0 deletions compatible.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"fullVersions": [
"0.111",
"0.110",
"0.109",
"0.108",
"0.107",
"0.106",
"0.105",
"0.104",
"0.103"
],
"lightVersions": [
"0.3",
"0.2"
Comment thread
homura marked this conversation as resolved.
],
"compatible": {
"0.111": {
"full": [
"0.111",
"0.110",
"0.109"
],
"light": [
"0.3",
"0.2"
]
},
"0.110": {
"full": [
"0.111",
"0.110",
"0.109"
],
"light": [
"0.3",
"0.2"
]
},
"0.106": {
"full": [
"0.108",
"0.107",
"0.106",
"0.105"
],
"light": []
},
"0.103": {
"full": [
"0.104",
"0.103"
],
"light": []
}
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"postinstall": "husky install",
"db:chain": "node ./node_modules/.bin/typeorm",
"update:valid-target": "node ./scripts/update-valid-target.js",
"update:neuron-compatible": "node ./scripts/add-neuron-version-in-compatibility-table.js",
"update:client-versions": "node ./scripts/update-ckb-client-versions.js"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/neuron-wallet/electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ afterSign: scripts/notarize.js
files:
- from: "../.."
to: "."
filter: ["!**/*", ".ckb-version", ".ckb-light-version", "ormconfig.json", "compatible.csv"]
filter: ["!**/*", ".ckb-version", ".ckb-light-version", "ormconfig.json", "compatible.json"]
- package.json
- dist
- ".env"
Expand Down
27 changes: 12 additions & 15 deletions packages/neuron-wallet/src/services/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,23 +231,20 @@ class NodeService {

private getNeuronCompatibilityCKB() {
const appPath = electronApp.isPackaged ? electronApp.getAppPath() : path.join(__dirname, '../../../..')
const compatiblePath = path.join(appPath, 'compatible.csv')
const compatiblePath = path.join(appPath, 'compatible.json')
if (fs.existsSync(compatiblePath)) {
try {
const content = fs.readFileSync(compatiblePath, 'utf8')?.split('\n')
const ckbVersions = content?.[0]?.split(',')?.slice(1)
const neuronCompatible = content?.slice(2)
const result: Record<string, Record<string, boolean>> = {}
for (let index = 0; index < neuronCompatible.length; index++) {
const [neuronVersion, ...campatibleValues] = neuronCompatible[index].split(',')
result[neuronVersion] = {}
campatibleValues.forEach((v, idx) => {
result[neuronVersion][ckbVersions[idx]] = v === 'yes'
})
}
return result
// eslint-disable-next-line @typescript-eslint/no-var-requires
const content = require(compatiblePath)
return (content?.compatible ?? {}) as Record<
string,
{
full: string[]
light: string[]
}
>
} catch (err) {
logger.error('App\t: get compatible table failed')
logger.error('App\t: get compatible failed', err)
}
}
}
Expand All @@ -256,7 +253,7 @@ class NodeService {
const compatibilities = this.getNeuronCompatibilityCKB()
const neuronCompatibleVersion = neuronVersion.split('.').slice(0, 2).join('.')
const externalCKBCompatibleVersion = externalCKBVersion.split('.').slice(0, 2).join('.')
return compatibilities?.[neuronCompatibleVersion]?.[externalCKBCompatibleVersion]
return compatibilities?.[neuronCompatibleVersion]?.full?.includes(externalCKBCompatibleVersion)
}

private verifyCKbNodeShouldUpdate(neuronCKBVersion: string, externalCKBVersion: string) {
Expand Down
42 changes: 29 additions & 13 deletions packages/neuron-wallet/tests/services/node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ describe('NodeService', () => {
const rpcRequestMock = jest.fn()
const getChainMock = jest.fn()
const getLocalNodeInfoMock = jest.fn()
const pathJoinMock = jest.fn()
const redistCheckMock = jest.fn()

const fakeHTTPUrl = 'http://fakeurl'

Expand All @@ -54,6 +56,8 @@ describe('NodeService', () => {
getLocalNodeInfoMock.mockReset()
stubbedStartLightNode.mockReset()
stubbedStopLightNode.mockReset()
pathJoinMock.mockReset()
redistCheckMock.mockReset()
}

beforeEach(() => {
Expand Down Expand Up @@ -173,6 +177,12 @@ describe('NodeService', () => {
}
})

jest.doMock('path', () => ({
join: pathJoinMock,
}))

jest.doMock('utils/redist-check', () => redistCheckMock)

stubbedRxjsDebounceTime.mockReturnValue((x: any) => x)
getChainMock.mockRejectedValue('no chain')
})
Expand Down Expand Up @@ -345,6 +355,7 @@ describe('NodeService', () => {
nodeService.ckb.node.url = bundledNodeUrl
})
stubbedStartCKBNode.mockResolvedValue(true)
redistCheckMock.mockResolvedValue(true)
stubbedNetworsServiceGet.mockReturnValue({ remote: bundledNodeUrl, readonly: true })
getLocalNodeInfoMock.mockRejectedValue('not start')
await nodeService.tryStartNodeOnDefaultURI()
Expand Down Expand Up @@ -409,10 +420,7 @@ describe('NodeService', () => {
nodeService = new NodeService()
nodeService.getNeuronCompatibilityCKB = () => ({
'0.110': {
'0.110': true,
'0.109': true,
'0.108': false,
'0.107': false,
full: ['0.110', '0.109'],
},
})
stubbedNetworsServiceGet.mockReturnValue({ remote: BUNDLED_CKB_URL, readonly: true })
Expand Down Expand Up @@ -456,10 +464,7 @@ describe('NodeService', () => {
nodeService = new NodeService()
nodeService.getNeuronCompatibilityCKB = () => ({
'0.110': {
'0.110': true,
'0.109': true,
'0.108': false,
'0.107': false,
full: ['0.110', '0.109'],
},
})
stubbedNetworsServiceGet.mockReturnValueOnce({ remote: BUNDLED_CKB_URL, readonly: true })
Expand Down Expand Up @@ -525,21 +530,32 @@ describe('NodeService', () => {
})
it('read file error', () => {
existsSyncMock.mockReturnValue(true)
readFileSyncMock.mockReturnValue(new Error('read failed'))
pathJoinMock.mockReturnValue('./not-exist.json')
expect(nodeService.getNeuronCompatibilityCKB()).toBeUndefined()
})
it('ckb version content is wrong', async () => {
existsSyncMock.mockReturnValue(true)
readFileSyncMock.mockReturnValue('')
pathJoinMock.mockReturnValue('exist.json')
jest.doMock('exist.json', () => ({}), { virtual: true })
expect(nodeService.getNeuronCompatibilityCKB()).toStrictEqual({})
})
it('success', async () => {
existsSyncMock.mockReturnValue(true)
readFileSyncMock.mockReturnValue('ckb,0.110,0.109\nNeuron,,\n0.109,yes,no')
pathJoinMock.mockReturnValue('success.json')
jest.doMock(
'success.json',
() => ({
compatible: {
'0.109': {
full: ['0.108'],
},
},
}),
{ virtual: true }
)
expect(nodeService.getNeuronCompatibilityCKB()).toStrictEqual({
'0.109': {
'0.110': true,
'0.109': false,
full: ['0.108'],
},
})
})
Expand Down
27 changes: 27 additions & 0 deletions scripts/add-neuron-version-in-compatibility-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const fs = require('node:fs')
const path = require('node:path')

const exec = () => {
const compatiblePath = path.resolve(__dirname, '../compatible.json')
const info = require(compatiblePath)
const packagePath = path.resolve(__dirname, '../package.json')
const neuronReleaseVersion = require(packagePath).version
const newNeuronVersion = neuronReleaseVersion.slice(0, neuronReleaseVersion.lastIndexOf('.'))

const lastNeuronVersion = Object.keys(info.compatible).sort((a, b) => {
const [aMajor, aMinor] = a.split('.')?.map(v => +v) ?? []
const [bMajor, bMinor] = b.split('.')?.map(v => +v) ?? []
if (aMajor !== bMajor) return bMajor - aMajor
return bMinor - aMinor
})[0]

if (newNeuronVersion && lastNeuronVersion !== newNeuronVersion) {
info.compatible[newNeuronVersion] = info.compatible[lastNeuronVersion]
fs.writeFileSync(compatiblePath, `${JSON.stringify(info, null, 2)}\r\n`)
} else {
process.exit(1)
}
}

exec()

40 changes: 40 additions & 0 deletions scripts/update-ckb-client-versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,57 @@ const fetchBuiltinCkbVersion = async () => {
}
}

const getMajorAndMinorVersion = (full) => {
// v0.3.0 -> 0.3
return full.slice(1, full.lastIndexOf('.'))
}

const updateCompatible = ({
node,
lightClient,
}) => {
const compatiblePath = path.resolve(__dirname, '../compatible.json')
const info = require(compatiblePath)
const lastFullVersion = info.fullVersions[0]
if (node && lastFullVersion !== node) {
info.fullVersions.unshift(node)
Object.values(info.compatible).forEach(v => {
if (v.full.includes(lastFullVersion)) {
v.full.unshift(node)
}
})
}
const lastLightVersion = info.lightVersions[0]
if (lightClient && lastLightVersion !== lightClient) {
info.lightVersions.unshift(lightClient)
Object.values(info.compatible).forEach(v => {
if (v.light.includes(lastLightVersion)) {
v.light.unshift(lightClient)
}
})
}
fs.writeFileSync(compatiblePath, `${JSON.stringify(info, null, 2)}\r\n`)
}

const exec = async () => {
const latestVersions = await fetchCkbLatestVersion()
const builtinVersions = await fetchBuiltinCkbVersion()

const compatibleUpdaterParams = {
node: undefined,
lightClient: undefined,
}
if (latestVersions.node !== builtinVersions.node) {
fs.writeFileSync(BUILTIN_VERSION_PATH.node, `${latestVersions.node}\n`)
compatibleUpdaterParams.node = getMajorAndMinorVersion(latestVersions.node)
}

if (latestVersions.lightClient !== builtinVersions.lightClient) {
fs.writeFileSync(BUILTIN_VERSION_PATH.lightClient, `${latestVersions.lightClient}\n`)
compatibleUpdaterParams.lightClient = getMajorAndMinorVersion(latestVersions.lightClient)
}

updateCompatible(compatibleUpdaterParams)
}

exec()