Skip to content

Commit

Permalink
Fix js image creation 2 (#1027)
Browse files Browse the repository at this point in the history
* Fix docker js_server image

* Fix for prettier ignore

* Remove tab

* Remove .prettierignore

* Make the JS docker image build at publish time and run tests on it against the live contract

* remove hard coded version

* remove unnecessary rm

* remove reference to .prettierignore

* fix html and add ignore rules

* move build steps

* lint

* lint

---------

Co-authored-by: forgetso <[email protected]>
  • Loading branch information
goastler and forgetso authored Feb 7, 2024
1 parent 8bf9e87 commit b72d45d
Show file tree
Hide file tree
Showing 15 changed files with 249 additions and 469 deletions.
10 changes: 10 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
**/*bundle*.js
**/ProcaptchaWidget-*.js
**/index-*.js
**/typechain/*
.yarn
node_modules
Expand Down Expand Up @@ -31,3 +33,11 @@ typings/
build/
protocol/target
.next
.eslintignore
.dockerignore
.gitignore
.npmignore
.nvmrc
diagram.svg
.env.*
.prettierignore
63 changes: 48 additions & 15 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,54 @@ jobs:
NODE_ENV=production npm run bundle:prod
- name: Build docker js_server
if: steps.check_version_any.outputs.bump == 'true'
run: |
docker pull prosopo/js_server:${{ steps.check_version_docker_js_server.outputs.version }}
# Create a temporary container from the latest image
echo "Building Docker image..."
OLD_CONTAINER_ID=$(docker create prosopo/js_server:${{ steps.check_version_docker_js_server.outputs.version }})
# Remove the old js temp folder
rm -rf ./js_bundles_host_temp
# Copy out the old files
docker cp $OLD_CONTAINER_ID:$JS_FOLDER ./js_bundles_host_temp
# Build the new image
docker build --file ./docker/images/js.server.dockerfile . -t prosopo/js_server:${{ steps.next_version.outputs.version }} --no-cache
# Run the new image
NEW_CONTAINER_ID=$(docker create prosopo/js_server:${{ steps.next_version.outputs.version }})
# Set the JS location in the container
JS_FOLDER="/usr/share/nginx/html/js"
# Copy the legacy files across
docker cp ./js_bundles_host_temp/ $NEW_CONTAINER_ID:$JS_FOLDER/
# Copy the new bundle files to the container into a folder with the version name
docker cp packages/procaptcha-bundle/dist/bundle/. $NEW_CONTAINER_ID:$JS_FOLDER
# Start the new container
docker start $NEW_CONTAINER_ID
# Move procaptcha.bundle.js
docker exec $NEW_CONTAINER_ID mv $JS_FOLDER/procaptcha.bundle.js $JS_FOLDER/procaptcha.bundle.${{ steps.next_version.outputs.version }}.js
# Symlink JS_FOLDER/procaptcha.bundle.js to JS_FOLDER/procaptcha.bundle.VERSION.js
docker exec $NEW_CONTAINER_ID ln -sf $JS_FOLDER/procaptcha.bundle.${{ steps.next_version.outputs.version }}.js $JS_FOLDER/procaptcha.bundle.js
# Commit the changes to the container
docker commit $NEW_CONTAINER_ID prosopo/js_server:${{ steps.next_version.outputs.version }}
# Check this new docker image works locally
docker run -p 3080:80 prosopo/js_server:${{ steps.next_version.outputs.version }}
# Run the cypress tests against the new bundle
npm run -w @prosopo/cypress-shared cypress:open:client-bundle-example:js_server
- name: Github release
continue-on-error: true
id: publish_github
Expand Down Expand Up @@ -416,21 +464,6 @@ jobs:
id: publish_docker_js_server
if: steps.check_version_docker_js_server.outputs.bump == 'true'
run: |
docker pull prosopo/js_server:${{ steps.check_version_docker_js_server.outputs.version }}
# Create a temporary container from the latest image
echo "Building Docker image..."
CONTAINER_ID=$(docker create prosopo/js_server:${{ steps.check_version_docker_js_server.outputs.version }})
# Copy the bundle to the container and rename it to include the version
docker cp packages/procaptcha-bundle/dist/bundle/procaptcha.bundle.js $CONTAINER_ID:/usr/share/nginx/html/js/procaptcha.bundle.${{ steps.next_version.outputs.version }}.js
# Copy the bundle to the container as the latest version, overwriting the existing bundle if one exists
docker cp packages/procaptcha-bundle/dist/bundle/procaptcha.bundle.js $CONTAINER_ID:/usr/share/nginx/html/js/procaptcha.bundle.js
# Commit the changes to the container
docker commit $CONTAINER_ID prosopo/js_server:${{ steps.next_version.outputs.version }}
# Push the new image to Docker Hub
echo "Pushing Docker image..."
docker push prosopo/js_server:${{ steps.next_version.outputs.version }}
Expand Down
4 changes: 2 additions & 2 deletions demos/client-bundle-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"npm": ">=9"
},
"scripts": {
"start": "light-server -s ./src -p 9232 -w \"**/*.html,**/*.css,**/*.js,**/*.gz\"",
"start": "vite serve ./src --port 9232 --config vite.config.ts",
"clean": "echo 'nothing to clean'",
"eslint": "npx eslint . --no-error-on-unmatched-pattern --ignore-path ../../.eslintignore",
"eslint:fix": "npm run eslint -- --fix",
Expand All @@ -17,7 +17,7 @@
},
"dependencies": {
"dotenv": "^16.0.1",
"light-server": "^2.9.1"
"vite": "^4.5.2"
},
"version": "0.2.33",
"devDependencies": {
Expand Down
22 changes: 22 additions & 0 deletions demos/client-bundle-example/src/jsBundleTest.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!doctype html>
<html lang="en">
<head>
<title>Procaptcha demo: Live Test</title>
<script
id="procaptchaScript"
type="module"
src="http://localhost:3080/js/procaptcha.bundle.js"
async
defer
></script>
</head>
<body>
<form>
<div
class="procaptcha"
data-theme="light"
data-sitekey="5HUBceb4Du6dvMA9BiwN5VzUrzUsX9Zp7z7nSR2cC1TCv5jg"
></div>
</form>
</body>
</html>
12 changes: 12 additions & 0 deletions demos/client-bundle-example/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.esm.json",
"compilerOptions": {
"lib": ["ES2021", "dom"],
"types": ["node"],
"noEmit": true,
"noEmitOnError": true,
"sourceMap": false
},
"include": ["**/*.ts"],
"references": []
}
9 changes: 9 additions & 0 deletions demos/client-bundle-example/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default {
watch: false,
mode: 'development',
server: {
https: false,
host: true,
cors: true,
},
}
3 changes: 3 additions & 0 deletions demos/cypress-shared/cypress.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { nodePolyfills } from 'vite-plugin-node-polyfills'
import vitePreprocessor from 'cypress-vite'
export default defineConfig({
headers: { 'Accept-Encoding': 'gzip, deflate' },
env: {
default_page: '/',
},
e2e: {
setupNodeEvents(on, config) {
on(
Expand Down
24 changes: 2 additions & 22 deletions demos/cypress-shared/cypress/e2e/captcha.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/// <reference types="cypress" />
import '@cypress/xpath'
import { Captcha } from '@prosopo/types'
import { ProsopoDatasetError } from '../../../../packages/common/src/error.js'
import { ProsopoDatasetError } from '@prosopo/common'
import { at } from '@prosopo/util'
import { checkboxClass } from '../support/commands.js'
import { datasetWithSolutionHashes } from '@prosopo/datasets'
Expand All @@ -34,7 +34,7 @@ describe('Captchas', () => {
cy.intercept('/dummy').as('dummy')

// visit the base URL specified on command line when running cypress
return cy.visit('/').then(() => {
return cy.visit(Cypress.env('default_page')).then(() => {
cy.get(checkboxClass).should('be.visible')
// wrap the solutions to make them available to the tests
cy.wrap(solutions).as('solutions')
Expand Down Expand Up @@ -68,26 +68,6 @@ describe('Captchas', () => {
})
})

it('Selecting the correct images passes the captcha', () => {
cy.clickIAmHuman().then(() => {
// Make sure the images are loaded
cy.captchaImages().then(() => {
// Solve the captchas
cy.get('@captchas')
.each((captcha: Captcha) => {
cy.log('in each function')
// Click correct images and submit the solution
cy.clickCorrectCaptchaImages(captcha)
})
.then(() => {
// Get inputs of type checkbox
cy.get("input[type='checkbox']").then((checkboxes) => {
cy.wrap(checkboxes).first().should('be.checked')
})
})
})
})
})
//
// it('Solution is rejected when incorrect', () => {
// const captchas = await cy.clickIAmHuman().promisify()
Expand Down
63 changes: 63 additions & 0 deletions demos/cypress-shared/cypress/e2e/correct.captcha.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright 2021-2023 Prosopo (UK) Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/// <reference types="cypress" />
import '@cypress/xpath'
import { Captcha } from '@prosopo/types'
import { ProsopoDatasetError } from '@prosopo/common'
import { checkboxClass } from '../support/commands.js'
import { datasetWithSolutionHashes } from '@prosopo/datasets'

describe('Captchas', () => {
beforeEach(() => {
const solutions = datasetWithSolutionHashes.captchas.map((captcha) => ({
captchaContentId: captcha.captchaContentId,
solution: captcha.solution,
}))

if (!solutions) {
throw new ProsopoDatasetError('DATABASE.DATASET_WITH_SOLUTIONS_GET_FAILED', {
context: { datasetWithSolutionHashes },
})
}
cy.intercept('/dummy').as('dummy')

// visit the base URL specified on command line when running cypress
return cy.visit(Cypress.env('default_page')).then(() => {
cy.get(checkboxClass).should('be.visible')
// wrap the solutions to make them available to the tests
cy.wrap(solutions).as('solutions')
})
})

it('Selecting the correct images passes the captcha', () => {
cy.clickIAmHuman().then(() => {
// Make sure the images are loaded
cy.captchaImages().then(() => {
// Solve the captchas
cy.get('@captchas')
.each((captcha: Captcha) => {
cy.log('in each function')
// Click correct images and submit the solution
cy.clickCorrectCaptchaImages(captcha)
})
.then(() => {
// Get inputs of type checkbox
cy.get("input[type='checkbox']").then((checkboxes) => {
cy.wrap(checkboxes).first().should('be.checked')
})
})
})
})
})
})
6 changes: 4 additions & 2 deletions demos/cypress-shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
"clean": "tsc --build --clean",
"cypress:open:client-example": "CYPRESS_BASE_URL='http://0.0.0.0:9230' cypress open",
"cypress:run:client-example": "CYPRESS_BASE_URL='http://0.0.0.0:9230' cypress run",
"cypress:open:client-bundle-example": "CYPRESS_BASE_URL='http://0.0.0.0:9232' cypress open",
"cypress:run:client-bundle-example": "CYPRESS_BASE_URL='http://0.0.0.0:9232' cypress run",
"cypress:open:client-bundle-example": "CYPRESS_BASE_URL='http://localhost:9232' cypress open",
"cypress:run:client-bundle-example": "CYPRESS_BASE_URL='http://localhost:9232' cypress run",
"cypress:open:client-bundle-example:js_server": "CYPRESS_BASE_URL='http://localhost:9232' cypress open --env default_page='/jsBundleTest.html' --spec 'cypress/e2e/captcha.cy.ts'",
"cypress:run:client-bundle-example:js_server": "CYPRESS_BASE_URL='http://localhost:9232' cypress run --env default_page='/jsBundleTest.html' --spec 'cypress/e2e/captcha.cy.ts'",
"eslint": "npx eslint . --no-error-on-unmatched-pattern --ignore-path ../../.eslintignore",
"eslint:fix": "npm run eslint -- --fix",
"prettier": "npx prettier . --check --no-error-on-unmatched-pattern --ignore-path ../../.eslintignore",
Expand Down
8 changes: 7 additions & 1 deletion dev/config/src/vite/vite.frontend.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ export default async function (
logger.debug(`aliases ${JSON.stringify(alias, null, 2)}`)

// drop console logs if in production mode
const drop: Drop[] | undefined = mode === 'production' ? ['console', 'debugger'] : undefined
let drop: undefined | Drop[]
let pure: string[] | undefined
if (isProduction) {
drop = ['debugger']
pure = ['console.log', 'console.warn']
}

logger.info('Bundle name', bundleName)
return {
Expand All @@ -93,6 +98,7 @@ export default async function (
platform: 'browser',
target: ['es2020', 'chrome60', 'edge18', 'firefox60', 'node12', 'safari11'],
drop,
pure,
legalComments: 'none',
},
define,
Expand Down
15 changes: 14 additions & 1 deletion dev/scripts/src/scripts/encodeDecode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { BN, hexToNumber, hexToString, hexToU8a, isHex, stringToHex, u8aToHex, u8aToString } from '@polkadot/util'
import { at } from '@prosopo/util'
import { blake2AsHex, isAddress } from '@polkadot/util-crypto'
import { decodeAddress, encodeAddress } from '@polkadot/keyring'
import { hexToNumber, hexToString, hexToU8a, isHex, stringToHex, u8aToHex, u8aToString } from '@polkadot/util'

// https://stackoverflow.com/a/75872362/1178971
function wrapItemToMultipleRows(item: { [key: string]: string }, maxCellWidth: number): { [key: string]: string }[] {
Expand Down Expand Up @@ -53,6 +53,15 @@ function isJSON(arg: string): boolean {
}
}

function isBN(arg: string): boolean {
try {
new BN(`0x${arg}`)
return true
} catch (e) {
return false
}
}

function main() {
const ss58Format = process.env.PROSOPO_SS58_FORMAT ? parseInt(process.env.PROSOPO_SS58_FORMAT) : 42
const arg = at(process.argv.slice(2), 0).trim()
Expand Down Expand Up @@ -105,6 +114,10 @@ function main() {
output.push({ name: `u8aToString`, value: u8aToString(padded) })
}

if (isBN(arg)) {
output.push({ name: `BN`, value: new BN(arg).toString() })
}

console.log('\nTABLE OUTPUT\n')
consoleTableWithWrapping(output)
console.log('\nJSON OUTPUT\n')
Expand Down
5 changes: 2 additions & 3 deletions docker/images/js.server.dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
FROM nginx:alpine

COPY ./js_bundles_host_temp/ /usr/share/nginx/html/js/
FROM nginx:latest
COPY ./docker/images/js.server.nginx.conf /etc/nginx/conf.d/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ server {
listen 80;
listen [::]:80;
server_name localhost;
http2: on;
http2 on;

#access_log /var/log/nginx/host.access.log main;

Expand Down
Loading

0 comments on commit b72d45d

Please sign in to comment.