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
92 changes: 92 additions & 0 deletions .github/workflows/build-and-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Build & Publish

on:
push:
branches: [develop, master]
pull_request:
branches: [develop, master]

permissions:
id-token: write
contents: write

jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Test
run: npm test
- name: Production dependency audit
run: npm audit --omit=dev
- name: Upload lib artifact
uses: actions/upload-artifact@v4
with:
name: lib
path: lib/

publish-prerelease:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
- run: npm ci
- run: npm run build
- name: Set pre-release version
run: |
BASE=$(node -p "require('./package.json').version")
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
npm version "${BASE}-pre.${SHORT_SHA}" --no-git-tag-version
- name: Publish pre-release (OIDC)
run: |
unset NODE_AUTH_TOKEN
npm publish --provenance --access public --tag pre

publish-stable:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
permissions:
id-token: write
contents: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '24'
- run: npm ci
- run: npm run build
- run: npm test
- name: Publish to npm (OIDC)
run: |
unset NODE_AUTH_TOKEN
PACKAGE=$(node -p "require('./package.json').name")
VERSION=$(node -p "require('./package.json').version")
if npm view "${PACKAGE}@${VERSION}" version >/dev/null 2>&1; then
echo "${PACKAGE}@${VERSION} is already published; skipping"
else
npm publish --provenance --access public
fi
- name: Create git tag
run: |
VERSION=$(node -p "require('./package.json').version")
if git ls-remote --exit-code --tags origin "refs/tags/v${VERSION}" >/dev/null 2>&1; then
echo "v${VERSION} already exists; skipping"
else
git tag "v${VERSION}"
git push origin "v${VERSION}"
fi
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@keepkey/device-protocol",
"version": "7.14.1",
"name": "@bithighlander/device-protocol",
"version": "7.18.0",
"publishConfig": {
"access": "public"
},
Expand All @@ -13,11 +13,11 @@
"build:postprocess": "node tools/postprocess-lib.js",
"prepare": "npm run build",
"prepublishOnly": "npm run build",
"test": "echo \"Error: no test specified\" && exit 1"
"test": "node test.js"
},
"repository": {
"type": "git",
"url": "git@gitlab.keepkey.com:client-software/device-protocol.git"
"url": "https://github.com/BitHighlander/device-protocol.git"
},
"author": "",
"license": "ISC",
Expand Down
76 changes: 76 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const fs = require('fs')
const path = require('path')

const libDir = path.join(__dirname, 'lib')
const requiredFiles = [
'proto.json',
'messages_pb.js',
'messages_pb.d.ts',
'types_pb.js',
'types_pb.d.ts',
'messages-ethereum_pb.js',
'messages-cosmos_pb.js',
'messages-binance_pb.js',
'messages-ripple_pb.js',
'messages-thorchain_pb.js',
'messages-osmosis_pb.js',
'messages-mayachain_pb.js',
'messages-solana_pb.js',
'messages-zcash_pb.js',
'messages-tron_pb.js',
'messages-ton_pb.js',
'messages-hive_pb.js',
'messages-near_pb.js',
]

let failed = 0
for (const file of requiredFiles) {
const filePath = path.join(libDir, file)
if (!fs.existsSync(filePath) || fs.statSync(filePath).size === 0) {
console.error(`FAIL: missing or empty ${file}`)
failed++
}
}

const proto = JSON.parse(fs.readFileSync(path.join(libDir, 'proto.json'), 'utf8'))
const hasNested = (name, value = proto) => {
if (!value || typeof value !== 'object') return false
if (Object.prototype.hasOwnProperty.call(value, name)) return true
return Object.values(value).some((child) => hasNested(name, child))
}

const requiredMessages = [
'GetBip85Mnemonic',
'SolanaSignTx',
'clearsign_certificate',
'EthereumSignTypedData',
'ZcashSignPCZT',
'HiveSignOperations',
'NearSignTx',
'TronGetAddress',
'TonGetAddress',
]

for (const message of requiredMessages) {
if (!hasNested(message)) {
console.error(`FAIL: proto.json missing ${message}`)
failed++
}
}

try {
const messages = require('./lib/messages_pb')
const types = require('./lib/types_pb')
console.log(`messages_pb exports ${Object.keys(messages).length} symbols`)
console.log(`types_pb exports ${Object.keys(types).length} symbols`)
} catch (error) {
console.error(`FAIL: generated modules do not load: ${error.message}`)
failed++
}

if (failed) {
console.error(`${failed} package validation check(s) failed`)
process.exit(1)
}

console.log('All package validation checks passed')
Loading