diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 00b13da72b..13562efa78 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -47,6 +47,11 @@ jobs: KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}" KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" KEYBASE_NYM_CHANNEL: "security" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" uses: docker://keybaseio/client:stable-node with: args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/build-ts-packages.yml b/.github/workflows/build-ts-packages.yml index 2dbf56ad7b..41c1348ace 100644 --- a/.github/workflows/build-ts-packages.yml +++ b/.github/workflows/build-ts-packages.yml @@ -58,6 +58,11 @@ jobs: KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" KEYBASE_NYM_CHANNEL: "ci-ts-packages" IS_SUCCESS: "${{ job.status == 'success' }}" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" uses: docker://keybaseio/client:stable-node with: args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad1f3d4d54..0eb21ddda7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ on: jobs: build: runs-on: [ self-hosted, custom-linux ] - # Enable sccache via environment variable + # Enable sccache via environment variable env: RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache steps: diff --git a/.github/workflows/network-explorer.yml b/.github/workflows/network-explorer.yml index 2f5b10de94..0745026fa9 100644 --- a/.github/workflows/network-explorer.yml +++ b/.github/workflows/network-explorer.yml @@ -73,6 +73,11 @@ jobs: KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" KEYBASE_NYM_CHANNEL: "ci-network-explorer" IS_SUCCESS: "${{ job.status == 'success' }}" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" uses: docker://keybaseio/client:stable-node with: args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/nightly_build.yml b/.github/workflows/nightly_build.yml index d103b66278..7fd70c8371 100644 --- a/.github/workflows/nightly_build.yml +++ b/.github/workflows/nightly_build.yml @@ -183,6 +183,11 @@ jobs: KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" KEYBASE_NYM_CHANNEL: "ci-nightly" IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" uses: docker://keybaseio/client:stable-node with: args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/nightly_build_release.yml b/.github/workflows/nightly_build_release.yml index 30e43d7f90..275237ddc9 100644 --- a/.github/workflows/nightly_build_release.yml +++ b/.github/workflows/nightly_build_release.yml @@ -198,6 +198,11 @@ jobs: KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" KEYBASE_NYM_CHANNEL: "ci-nightly-release" IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" uses: docker://keybaseio/client:stable-node with: args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/nightly_build_release2.yml b/.github/workflows/nightly_build_release2.yml index 6ff5368c56..28b9f8bf93 100644 --- a/.github/workflows/nightly_build_release2.yml +++ b/.github/workflows/nightly_build_release2.yml @@ -198,6 +198,11 @@ jobs: KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" KEYBASE_NYM_CHANNEL: "ci-nightly-release" IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" uses: docker://keybaseio/client:stable-node with: args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/nym-connect.yml b/.github/workflows/nym-connect.yml index 5a652e92d2..b13ff0bafe 100644 --- a/.github/workflows/nym-connect.yml +++ b/.github/workflows/nym-connect.yml @@ -54,6 +54,11 @@ jobs: KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" KEYBASE_NYM_CHANNEL: "ci-nym-connect" IS_SUCCESS: "${{ job.status == 'success' }}" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" uses: docker://keybaseio/client:stable-node with: args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/nym-wallet-storybook.yml b/.github/workflows/nym-wallet-storybook.yml index 7e4ead501f..c2fbea2d50 100644 --- a/.github/workflows/nym-wallet-storybook.yml +++ b/.github/workflows/nym-wallet-storybook.yml @@ -50,6 +50,11 @@ jobs: KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}" KEYBASE_NYM_CHANNEL: "ci-nym-wallet" IS_SUCCESS: "${{ job.status == 'success' }}" + MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" + MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" + MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" + MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" + MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" uses: docker://keybaseio/client:stable-node with: args: .github/workflows/support-files/notifications/entry_point.sh diff --git a/.github/workflows/support-files/.env.example b/.github/workflows/support-files/.env.example index f869af7605..82e3526223 100644 --- a/.github/workflows/support-files/.env.example +++ b/.github/workflows/support-files/.env.example @@ -2,6 +2,12 @@ KEYBASE_NYM_CHANNEL= KEYBASE_NYMBOT_USERNAME= KEYBASE_NYMBOT_PAPERKEY= +MATRIX_SERVER= +MATRIX_ROOM= +MATRIX_USER_ID= +MATRIX_TOKEN= +MATRIX_DEVICE_ID= + NYM_NOTIFICATION_KIND=nightly NYM_PROJECT_NAME=Nightly Build diff --git a/.github/workflows/support-files/.gitignore b/.github/workflows/support-files/.gitignore index 2ca1a3414b..37f81d053b 100644 --- a/.github/workflows/support-files/.gitignore +++ b/.github/workflows/support-files/.gitignore @@ -2,4 +2,6 @@ node_modules .idea # don't commit the lock file to avoid cross-platform issues -package-lock.json \ No newline at end of file +package-lock.json + +scratch \ No newline at end of file diff --git a/.github/workflows/support-files/notifications/send_message.js b/.github/workflows/support-files/notifications/send_message.js index 671e40bd84..4a6c0fb6af 100644 --- a/.github/workflows/support-files/notifications/send_message.js +++ b/.github/workflows/support-files/notifications/send_message.js @@ -1,6 +1,7 @@ require('dotenv').config(); const Bot = require('keybase-bot'); +const { sendMatrixMessage } = require('./send_message_to_matrix'); let context = { kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly', 'nym-connect','security'], @@ -38,6 +39,28 @@ function validateContext() { 'Paperkey is not defined. Please set env var KEYBASE_NYMBOT_PAPERKEY', ); } + if (context.env.MATRIX_ROOM) { + if (!context.env.MATRIX_SERVER) { + throw new Error( + 'Matrix server is not defined. Please set env var MATRIX_SERVER', + ); + } + if (!context.env.MATRIX_USER_ID) { + throw new Error( + 'Matrix user id is not defined. Please set env var MATRIX_USER_ID', + ); + } + if (!context.env.MATRIX_TOKEN) { + throw new Error( + 'Matrix token is not defined. Please set env var MATRIX_TOKEN', + ); + } + if (!context.env.MATRIX_DEVICE_ID) { + throw new Error( + 'Matrix device id is not defined. Please set env var MATRIX_DEVICE_ID', + ); + } + } } /** @@ -147,6 +170,9 @@ async function main() { console.log('-----------------------------------------'); } await sendKeybaseMessage(messageBody); + if(context.env.MATRIX_ROOM) { + await sendMatrixMessage(context, messageBody, context.env.MATRIX_ROOM) + } } // call main function and let NodeJS handle the promise diff --git a/.github/workflows/support-files/notifications/send_message_to_matrix.js b/.github/workflows/support-files/notifications/send_message_to_matrix.js new file mode 100644 index 0000000000..85f1849b93 --- /dev/null +++ b/.github/workflows/support-files/notifications/send_message_to_matrix.js @@ -0,0 +1,81 @@ +const sdk = require('matrix-js-sdk'); +global.Olm = require('olm'); +const { LocalStorage } = require('node-localstorage'); +const localStorage = new LocalStorage('./scratch'); +const { + LocalStorageCryptoStore, +} = require('matrix-js-sdk/lib/crypto/store/localStorage-crypto-store'); + +const vfile = require('to-vfile'); +const unified = require('unified'); +const remarkParse = require('remark-parse'); +const remarkHtml = require('remark-html'); +const emoji = require('remark-emoji'); + +// hide all matrix client output +console.error = (error) => console.log('❌ error: ', error); +process.stderr.write = () => {}; +process.stdout.write = () => {}; + + +function createClient(context, room, message) { + const server = context.env.MATRIX_SERVER; + const token = context.env.MATRIX_TOKEN; + const deviceId = context.env.MATRIX_DEVICE_ID; + const userId = context.env.MATRIX_USER_ID; + + const client = sdk.createClient({ + baseUrl: server, + accessToken: token, + userId, + deviceId, + sessionStore: new sdk.WebStorageSessionStore(localStorage), + cryptoStore: new LocalStorageCryptoStore(localStorage), + }); + + client.on('sync', async function(state, prevState, res) { + if (state !== 'PREPARED') return; + client.setGlobalErrorOnUnknownDevices(false); + try { + await client.joinRoom(room); + await client.sendEvent( + room, + 'm.room.message', + { + msgtype: 'm.text', + format: 'org.matrix.custom.html', + body: message, + formatted_body: message, + }, + '', + ); + } catch (error) { + console.error('Job failed: ' + error.message); + } + client.stopClient(); + process.exit(0); + }); + + return client; +} + +async function markdownToHtml(messageAsMarkdown) { + const file = await unified() + .use(emoji) + .use(remarkParse) + .use(remarkHtml) + .process(await vfile({ path: 'test.md', contents: messageAsMarkdown})); + console.log({file}); + return String(file); +} + +async function sendMatrixMessage(contextArg, messageAsMarkdown, roomId) { + const messageAsHtml = await markdownToHtml(messageAsMarkdown); + const client = createClient(contextArg, roomId, messageAsHtml); + await client.initCrypto(); + await client.startClient({ initialSyncLimit: 1 }); +} + +module.exports = { + sendMatrixMessage, +}; diff --git a/.github/workflows/support-files/package.json b/.github/workflows/support-files/package.json index b73f32259d..8f20c34091 100644 --- a/.github/workflows/support-files/package.json +++ b/.github/workflows/support-files/package.json @@ -11,7 +11,15 @@ "dotenv": "^16.0.0", "handlebars": "^4.7.7", "keybase-bot": "^3.6.1", - "octokit": "^1.7.1" + "matrix-js-sdk": "^9.3.0", + "node-localstorage": "^2.1.6", + "octokit": "^1.7.1", + "olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz", + "remark-emoji": "^2.2.0", + "remark-html": "^13.0.2", + "remark-parse": "^9.0.0", + "to-vfile": "^6.1.0", + "unified": "^9.2.2" }, "devDependencies": { "prettier": "2.3.2"