1
0
mirror of https://github.com/oceanprotocol/ocean.js.git synced 2024-11-26 20:39:05 +01:00

Replace Travis with GitHub Actions (#847)

* GitHub CI actions

* add coverage job

* test run tweaks

* windows build fix

* barge tweaks

* deal with env vars

* add npm publish job

* trial & error

* remove Travis

* publish as single workflow

* handle Docker Hub login

* maybe preparing ~/.ocean is needed

* downgrade barge contracts, run with barge defaults

* put back ADDRESS_FILE env var

* AQUARIUS_URI test

* ddo creation test logging

* make failing DDO creation test actually fail

* separate unit/integration Asset tests

* set AQUARIUS_URI again

* readme updates

* prepare ~/.ocean folder

* separate tests into multiple jobs

* address.json debugging

* windows build fixes

* address.json trials

* env var expansion workaround

* cleanup

* debug coverage output

* fix coverage

* bump codeclimate-action

* use barge instead of ganache (#855)

* use barge instead of ganache

* small unit test job cleanup

Co-authored-by: Matthias Kretschmann <m@kretschmann.io>

* barge detach workaround

Co-authored-by: Alex Coseru <alex.coseru@gmail.com>
This commit is contained in:
Matthias Kretschmann 2021-06-22 12:21:27 +02:00 committed by GitHub
parent decd504984
commit d8914a8380
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 357 additions and 215 deletions

160
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,160 @@
name: 'CI'
on:
push:
branches:
- main
tags:
- '**'
pull_request:
branches:
- '**'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache node_modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-lint-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-lint-${{ env.cache-name }}-
- run: npm ci
- run: npm run lint
test_unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache node_modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-test-unit-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-test-unit-${{ env.cache-name }}-
- name: Checkout Barge
uses: actions/checkout@v2
with:
repository: 'oceanprotocol/barge'
path: 'barge'
- name: Run Ganache with Barge
working-directory: ${{ github.workspace }}/barge
run: |
bash -x start_ocean.sh --no-aquarius --no-elasticsearch --no-provider --no-dashboard --skip-deploy 2>&1 > start_ocean.log &
cd ..
- run: npm ci
- run: npm run build:metadata
- run: npm run test:unit:cover
- uses: actions/upload-artifact@v2
with:
name: coverage
path: coverage/
test_integration:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- name: Cache node_modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-test-integration-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-test-integration-${{ env.cache-name }}-
- run: npm ci
- run: npm run build:metadata
# Env var expansion workaround
# https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
- name: Set ADDRESS_FILE
run: echo "ADDRESS_FILE=${HOME}/.ocean/ocean-contracts/artifacts/address.json" >> $GITHUB_ENV
- name: Checkout Barge
uses: actions/checkout@v2
with:
repository: 'oceanprotocol/barge'
path: 'barge'
- name: Login to Docker Hub
if: ${{ env.DOCKERHUB_PASSWORD && env.DOCKERHUB_USERNAME }}
run: |
echo "Login to Docker Hub";echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Run Barge
working-directory: ${{ github.workspace }}/barge
run: |
bash -x start_ocean.sh --with-provider2 --no-dashboard 2>&1 > start_ocean.log &
cd .. && ./scripts/waitforcontracts.sh
- run: npm run test:integration:cover
- uses: actions/upload-artifact@v2
with:
name: coverage
path: coverage/
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: ['15', '16']
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node }}
- name: Cache node_modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-${{ matrix.node }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-${{ matrix.node }}-build-${{ env.cache-name }}-
- run: npm ci
- run: npm run build
coverage:
runs-on: ubuntu-latest
needs: [test_unit, test_integration]
if: success()
steps:
- uses: actions/checkout@v2
- uses: actions/download-artifact@v2
with:
name: coverage
- uses: paambaati/codeclimate-action@v2.7.5
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
with:
coverageLocations: |
${{ github.workspace }}/unit/lcov.info:lcov
${{ github.workspace }}/integration/lcov.info:lcov

21
.github/workflows/publish.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: 'Publish'
on:
push:
tags:
- '**'
jobs:
npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
registry-url: https://registry.npmjs.org/
- run: npm ci
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -1,55 +0,0 @@
dist: xenial
sudo: required
language: node_js
node_js:
- 15
services:
- docker
cache: npm
matrix:
fast_finish: true
before_script:
# CodeClimate test reporter setup
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
- chmod +x ./cc-test-reporter
- ./cc-test-reporter before-build
# Barge setup
- git clone https://github.com/oceanprotocol/barge
- cd barge
- export ADDRESS_FILE="${HOME}/.ocean/ocean-contracts/artifacts/address.json"
- mkdir "${HOME}/.ocean/"
- mkdir "${HOME}/.ocean/ocean-contracts/"
- mkdir "${HOME}/.ocean/ocean-contracts/artifacts"
- touch $ADDRESS_FILE
- echo "{}" >> $ADDRESS_FILE
- export AQUARIUS_URI="http://172.15.0.5:5000"
- export DEPLOY_CONTRACTS="true"
- if [[ -n "$DOCKERHUB_PASSWORD" && -n "$DOCKERHUB_USERNAME" ]]; then echo "logining in to docker";echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin;fi
- bash -x start_ocean.sh --with-provider2 --no-dashboard 2>&1 > start_ocean.log &
- cd ..
- ./scripts/waitforcontracts.sh
script:
- npm test
- npm run build
after_script:
- ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.unit.json coverage/unit/lcov.info # Format unit test coverage
- ./cc-test-reporter format-coverage -t lcov -o coverage/codeclimate.integration.json coverage/integration/lcov.info # Format integration test coverage
- ./cc-test-reporter sum-coverage coverage/codeclimate.*.json -p 2 # Sum both coverage parts into coverage/codeclimate.json
- if [[ -n "CC_TEST_REPORTER_ID" && "$TRAVIS_TEST_RESULT" == 0 ]]; then ./cc-test-reporter upload-coverage; fi # Upload coverage/codeclimate.json
notifications:
email: false
deploy:
- provider: npm
email: 'devops@oceanprotocol.com'
api_key: ${NPM_TOKEN}
skip_cleanup: true
on:
tags: true

View File

@ -5,7 +5,7 @@
> JavaScript library to privately & securely publish, exchange, and consume data.
[![npm](https://img.shields.io/npm/v/@oceanprotocol/lib.svg)](https://www.npmjs.com/package/@oceanprotocol/lib)
[![Build Status](https://travis-ci.com/oceanprotocol/ocean.js.svg?token=soMi2nNfCZq19zS1Rx4i&branch=main)](https://travis-ci.com/oceanprotocol/ocean.js)
[![Build Status](https://github.com/oceanprotocol/ocean.js/workflows/CI/badge.svg)](https://github.com/oceanprotocol/ocean.js/actions)
[![Maintainability](https://api.codeclimate.com/v1/badges/6381c81b8ac568a53537/maintainability)](https://codeclimate.com/github/oceanprotocol/ocean.js/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/6381c81b8ac568a53537/test_coverage)](https://codeclimate.com/github/oceanprotocol/ocean.js/test_coverage)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-7b1173.svg?style=flat-square)](https://github.com/prettier/prettier)
@ -120,7 +120,7 @@ This batteries-included flow includes metadata, multiple services for one datato
If you have any difficulties with the quickstarts, or if you have further questions about how to use ocean.js please reach out to us on [Discord](https://discord.gg/TnXjkR5).
If you notice any bugs or issues with Ocean.js please [open an issue on github](https://github.com/oceanprotocol/ocean.js/issues/new?assignees=&labels=bug&template=bug_report.md&title=).
If you notice any bugs or issues with ocean.js please [open an issue on github](https://github.com/oceanprotocol/ocean.js/issues/new?assignees=&labels=bug&template=bug_report.md&title=).
## 🦑 Development
@ -147,7 +147,7 @@ npm run format
## 👩‍🔬 Testing
Test suite for unit & integration tests is setup with [Mocha](https://mochajs.org) as test runner, and [nyc](https://github.com/istanbuljs/nyc) for coverage reporting. A combined coverage report is sent to CodeClimate via Travis.
Test suite for unit & integration tests is setup with [Mocha](https://mochajs.org) as test runner, and [nyc](https://github.com/istanbuljs/nyc) for coverage reporting. A combined coverage report is sent to CodeClimate via the `coverage` GitHub Actions job.
Running all tests requires running Ocean Protocol components beforehand with [Barge](https://github.com/oceanprotocol/barge), which also runs a `ganache-cli` instance:
@ -160,7 +160,7 @@ cd barge
You can then proceed to run in another terminal.
Let ocean.js know where to pickup the smartcontract addresses:
Let ocean.js know where to pickup the smart contract addresses, which has been written out by Barge in this location:
```
export ADDRESS_FILE="${HOME}/.ocean/ocean-contracts/artifacts/address.json"
@ -169,7 +169,7 @@ export ADDRESS_FILE="${HOME}/.ocean/ocean-contracts/artifacts/address.json"
Build metadata:
```
npm run build
npm run build:metadata
```
Executing linting, type checking, unit, and integration tests with coverage reporting all in one go:
@ -225,7 +225,7 @@ The task does the following:
- creates a Git tag
- commits and pushes everything
- creates a GitHub release with commit messages as description
- Git tag push will trigger Travis to do a npm release
- Git tag push will trigger a GitHub Action workflow to do a npm release
For the GitHub releases steps a GitHub personal access token, exported as `GITHUB_TOKEN` is required. [Setup](https://github.com/release-it/release-it#github-releases)

View File

@ -13,13 +13,13 @@
"start": "npm run clean && npm run build:metadata && tsc -w",
"build": "npm run clean && npm run build:metadata && microbundle build --format umd,cjs,es --compress --target node --tsconfig tsconfig.json",
"build:tsc": "tsc --sourceMap",
"build:metadata": "./scripts/get-metadata.js > src/metadata.json",
"build:metadata": "node ./scripts/get-metadata.js > src/metadata.json",
"clean": "rm -rf ./dist/ ./doc/ ./.nyc_output",
"lint": "eslint --ignore-path .gitignore --ext .ts,.tsx . && npm run type-check",
"lint:fix": "eslint --ignore-path .gitignore --ext .ts,.tsx . --fix",
"format": "prettier --parser typescript --ignore-path .gitignore --write '**/*.{js,jsx,ts,tsx}'",
"type-check": "npm run build:metadata && tsc --noEmit",
"doc:json": "./scripts/typedoc.js",
"doc:json": "node ./scripts/typedoc.js",
"run": "ts-node",
"release": "release-it --non-interactive",
"changelog": "auto-changelog -p",

View File

@ -1,8 +1,7 @@
if [ "${DEPLOY_CONTRACTS}" = "true" ]; then
while [ ! -f "${HOME}/.ocean/ocean-contracts/artifacts/ready" ]; do
sleep 2
done
fi
while [ ! -f "${HOME}/.ocean/ocean-contracts/artifacts/ready" ]; do
sleep 2
done
cat "barge/start_ocean.log"
ls -lh "${HOME}/.ocean/ocean-contracts/"
ls -lh "${HOME}/.ocean/ocean-contracts/artifacts/"

View File

@ -0,0 +1,161 @@
import { assert } from 'chai'
import { Ocean } from '../../src/ocean/Ocean'
import Web3 from 'web3'
import { Account, DDO, CredentialType, ConfigHelper, Metadata } from '../../src/lib'
const web3 = new Web3('http://127.0.0.1:8545')
describe('Assets', () => {
let ocean: Ocean
let alice: Account
let bob: Account
let charlie: Account
let ddo: DDO
let ddoWithAddressAnd3Box: DDO
const addressType = CredentialType.address
const threeBoxType = CredentialType.credential3Box
let walletA: string
let walletB: string
let walletC: string
const threeBoxValue = 'did:3:bafyre'
beforeEach(async () => {
const config = new ConfigHelper().getConfig('development')
config.web3Provider = web3
ocean = await Ocean.getInstance(config)
alice = (await ocean.accounts.list())[1]
walletA = alice.getId()
bob = (await ocean.accounts.list())[2]
walletB = bob.getId()
charlie = (await ocean.accounts.list())[3]
walletC = charlie.getId()
})
it('Alice creates a DDO', async () => {
const metadata: Metadata = {
main: {
type: 'dataset',
name: 'test-dataset',
dateCreated: new Date(Date.now()).toISOString().split('.')[0] + 'Z', // remove milliseconds
author: 'oceanprotocol-team',
license: 'MIT',
files: [
{
url: 'https://s3.amazonaws.com/testfiles.oceanprotocol.com/info.0.json',
checksum: 'efb2c764274b745f5fc37f97c6b0e761',
contentLength: '4535431',
contentType: 'text/csv',
encoding: 'UTF-8',
compression: 'zip'
}
]
}
}
const price = '10' // in datatoken
const publishedDate = new Date(Date.now()).toISOString().split('.')[0] + 'Z'
const timeout = 0
const service1 = await ocean.assets.createAccessServiceAttributes(
alice,
price,
publishedDate,
timeout
)
ddo = await ocean.assets.create(metadata, alice, [service1])
assert.isDefined(ddo)
assert.isDefined(ddo.id)
// const storeTx = await ocean.onChainMetadata.publish(ddo.id, ddo, alice.getId())
// assert(storeTx)
// await waitForAqua(ocean, ddo.id)
})
it('should add allow credential', async () => {
assert(ocean.assets.checkCredential(ddo, addressType, walletA).status === 0)
assert(ocean.assets.checkCredential(ddo, addressType, walletC).status === 0)
const allowWalletAddressList = [walletA, walletB]
console.error(JSON.stringify(ddo.credentials))
const newDdo = await ocean.assets.updateCredentials(
ddo,
addressType,
allowWalletAddressList,
[]
)
assert(newDdo.credentials.allow.length === 1)
assert(ocean.assets.checkCredential(ddo, addressType, walletA).status === 0)
assert(ocean.assets.checkCredential(ddo, addressType, walletC).status === 2)
})
it('should append allow credential', async () => {
const allowWalletAddressList = [walletA, walletB]
const allow3BoxList = [threeBoxValue]
ddoWithAddressAnd3Box = await ocean.assets.updateCredentials(
ddo,
addressType,
allowWalletAddressList,
[]
)
ddoWithAddressAnd3Box = await ocean.assets.updateCredentials(
ddo,
threeBoxType,
allow3BoxList,
[]
)
assert(ddoWithAddressAnd3Box.credentials.allow.length === 2)
})
it('should add deny credential', async () => {
const denyWalletAddressList = [walletC]
const newDdo = await ocean.assets.updateCredentials(
ddo,
addressType,
[],
denyWalletAddressList
)
assert(newDdo.credentials.deny.length === 1)
assert(ocean.assets.checkCredential(ddo, addressType, walletA).status === 0)
assert(ocean.assets.checkCredential(ddo, addressType, walletC).status === 3)
})
it('should append deny credential', async () => {
const denyWalletAddressList = [walletC]
const deny3BoxList = [threeBoxValue]
let newDdo = await ocean.assets.updateCredentials(
ddo,
addressType,
[],
denyWalletAddressList
)
newDdo = await ocean.assets.updateCredentials(ddo, threeBoxType, [], deny3BoxList)
assert(newDdo.credentials.deny.length === 2)
})
it('should only remove allow credential by credential type', async () => {
const allowWalletAddressList = [walletA, walletB]
const allow3BoxList = [threeBoxValue]
let newDdo = await ocean.assets.updateCredentials(
ddo,
addressType,
allowWalletAddressList,
[]
)
newDdo = await ocean.assets.updateCredentials(
ddoWithAddressAnd3Box,
threeBoxType,
allow3BoxList,
[]
)
assert(newDdo.credentials.allow.length === 2)
newDdo = await ocean.assets.updateCredentials(
ddoWithAddressAnd3Box,
threeBoxType,
[],
[]
)
assert(newDdo.credentials.allow.length === 1)
assert(ocean.assets.checkCredential(ddo, addressType, walletA).status === 0)
assert(ocean.assets.checkCredential(ddo, addressType, walletC).status === 2)
})
})

View File

@ -7,7 +7,5 @@ export default {
metadataCacheUri: 'http://localhost:5000',
providerUri: 'http://localhost:8030',
nodeUri: `http://localhost:${process.env.ETH_PORT || 8545}`,
parityUri: 'http://localhost:9545',
secretStoreUri: 'http://localhost:12001',
verbose: LogLevel.Error
} as Config

View File

@ -3,40 +3,19 @@ import spies from 'chai-spies'
import { SearchQuery, MetadataCache } from '../../../src/metadatacache/MetadataCache'
import { Ocean } from '../../../src/ocean/Ocean'
import Web3 from 'web3'
import { Account, DDO, CredentialType, ConfigHelper } from '../../../src/lib'
import { DDO, ConfigHelper } from '../../../src/lib'
import { responsify, getSearchResults } from '../helpers'
const web3 = new Web3('http://127.0.0.1:8545')
use(spies)
describe('Assets', () => {
let ocean: Ocean
let metadataCache: MetadataCache
let asset: any
let owner: Account
let alice: Account
let bob: Account
let charlie: Account
let ddo: DDO
let ddoWithAddressAnd3Box: DDO
const addressType = CredentialType.address
const threeBoxType = CredentialType.credential3Box
let walletA: string
let walletB: string
let walletC: string
const threeBoxValue = 'did:3:bafyre'
beforeEach(async () => {
const config = new ConfigHelper().getConfig('development')
config.web3Provider = web3
ocean = await Ocean.getInstance(config)
metadataCache = ocean.metadataCache // eslint-disable-line prefer-destructuring
owner = (await ocean.accounts.list())[0]
alice = (await ocean.accounts.list())[1]
walletA = alice.getId()
bob = (await ocean.accounts.list())[2]
walletB = bob.getId()
charlie = (await ocean.accounts.list())[3]
walletC = charlie.getId()
})
afterEach(() => {
@ -78,125 +57,4 @@ describe('Assets', () => {
assert.isDefined(assets.results[0].findServiceById)
})
})
it('Generates metadata', async () => {
asset = {
main: {
type: 'dataset',
name: 'test-dataset',
dateCreated: new Date(Date.now()).toISOString().split('.')[0] + 'Z', // remove milliseconds
author: 'oceanprotocol-team',
license: 'MIT',
files: [
{
url: 'https://s3.amazonaws.com/testfiles.oceanprotocol.com/info.0.json',
checksum: 'efb2c764274b745f5fc37f97c6b0e761',
contentLength: '4535431',
contentType: 'text/csv',
encoding: 'UTF-8',
compression: 'zip'
}
]
}
}
})
it('Alice creates a DDO', async () => {
const price = '10' // in datatoken
const publishedDate = new Date(Date.now()).toISOString().split('.')[0] + 'Z'
const timeout = 0
const service1 = await ocean.assets.createAccessServiceAttributes(
alice,
price,
publishedDate,
timeout
)
ddo = await ocean.assets.create(asset, alice, [service1], null)
})
it('should add allow credential', async () => {
assert(ocean.assets.checkCredential(ddo, addressType, walletA).status === 0)
assert(ocean.assets.checkCredential(ddo, addressType, walletC).status === 0)
const allowWalletAddressList = [walletA, walletB]
console.error(JSON.stringify(ddo.credentials))
const newDdo = await ocean.assets.updateCredentials(
ddo,
addressType,
allowWalletAddressList,
[]
)
assert(newDdo.credentials.allow.length === 1)
assert(ocean.assets.checkCredential(ddo, addressType, walletA).status === 0)
assert(ocean.assets.checkCredential(ddo, addressType, walletC).status === 2)
})
it('should append allow credential', async () => {
const allowWalletAddressList = [walletA, walletB]
const allow3BoxList = [threeBoxValue]
ddoWithAddressAnd3Box = await ocean.assets.updateCredentials(
ddo,
addressType,
allowWalletAddressList,
[]
)
ddoWithAddressAnd3Box = await ocean.assets.updateCredentials(
ddo,
threeBoxType,
allow3BoxList,
[]
)
assert(ddoWithAddressAnd3Box.credentials.allow.length === 2)
})
it('should add deny credential', async () => {
const denyWalletAddressList = [walletC]
const newDdo = await ocean.assets.updateCredentials(
ddo,
addressType,
[],
denyWalletAddressList
)
assert(newDdo.credentials.deny.length === 1)
assert(ocean.assets.checkCredential(ddo, addressType, walletA).status === 0)
assert(ocean.assets.checkCredential(ddo, addressType, walletC).status === 3)
})
it('should append deny credential', async () => {
const denyWalletAddressList = [walletC]
const deny3BoxList = [threeBoxValue]
let newDdo = await ocean.assets.updateCredentials(
ddo,
addressType,
[],
denyWalletAddressList
)
newDdo = await ocean.assets.updateCredentials(ddo, threeBoxType, [], deny3BoxList)
assert(newDdo.credentials.deny.length === 2)
})
it('should only remove allow credential by credential type', async () => {
const allowWalletAddressList = [walletA, walletB]
const allow3BoxList = [threeBoxValue]
let newDdo = await ocean.assets.updateCredentials(
ddo,
addressType,
allowWalletAddressList,
[]
)
newDdo = await ocean.assets.updateCredentials(
ddoWithAddressAnd3Box,
threeBoxType,
allow3BoxList,
[]
)
assert(newDdo.credentials.allow.length === 2)
newDdo = await ocean.assets.updateCredentials(
ddoWithAddressAnd3Box,
threeBoxType,
[],
[]
)
assert(newDdo.credentials.allow.length === 1)
assert(ocean.assets.checkCredential(ddo, addressType, walletA).status === 0)
assert(ocean.assets.checkCredential(ddo, addressType, walletC).status === 2)
})
})