Merge branch 'master' into refactoring-static-analyser

pull/1104/head
David Zagi 4 years ago committed by GitHub
commit a053eefe5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .circleci/config.yml
  2. 4
      apps/remix-ide-e2e/src/commands/debugTransaction.ts
  3. 22
      apps/remix-ide-e2e/src/commands/goToVMTraceStep.ts
  4. 5
      apps/remix-ide-e2e/src/commands/testFunction.ts
  5. 2
      apps/remix-ide/src/app.js
  6. 9
      apps/remix-ide/src/app/files/fileManager.js
  7. 2
      apps/remix-ide/src/app/panels/file-panel.js
  8. 5
      apps/remix-ide/src/app/panels/tab-proxy.js
  9. 4
      apps/remix-ide/src/app/tabs/runTab/settings.js
  10. 71
      apps/remix-ide/src/app/ui/landing-page/landing-page.js
  11. 9
      apps/remix-ide/src/migrateFileSystem.js
  12. 2
      libs/remix-ui/file-explorer/src/lib/file-explorer.tsx
  13. 7
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  14. 43
      release-management.md
  15. 94
      release-process.md

@ -31,9 +31,6 @@ jobs:
- run:
name: Remix IDE e2e Linting
command: npm run lint remix-ide-e2e
- run: npm run lint:libs
- run: npm run lint
- run: npm run lint remix-ide-e2e
remix-libs:
docker:

@ -14,12 +14,12 @@ class debugTransaction extends EventEmitter {
}
function checkStyle (browser: NightwatchBrowser, index: number, callback: VoidFunction) {
browser.pause(2000).execute(function (index: number) {
browser.pause(5000).execute(function (index: number) {
const debugBtn = document.querySelectorAll('*[data-shared="txLoggerDebugButton"]')[index] as HTMLInputElement
debugBtn && debugBtn.click()
}, [index], function () {
browser.waitForElementVisible('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]').perform(() => callback())
browser.waitForElementVisible('*[data-id="buttonNavigatorJumpPreviousBreakpoint"]', 60000).perform(() => callback())
})
}

@ -10,25 +10,11 @@ class GoToVmTraceStep extends EventEmitter {
}
function goToVMtraceStep (browser: NightwatchBrowser, step: number, incr: number, done: VoidFunction) {
if (!incr) incr = 0
browser.execute(function () {
return document.querySelector('#stepdetail').innerHTML
}, [], function (result) {
if (typeof result.value === 'string' && (result.value.indexOf('vm trace step:') !== -1 && result.value.indexOf(step.toString()) !== -1)) {
browser.execute(function (step) { (document.getElementById('slider') as HTMLInputElement).value = (step - 1).toString() }, [step])
.setValue('*[data-id="slider"]', new Array(1).fill(browser.Keys.RIGHT_ARROW))
.perform(() => {
done()
} else if (incr > 1000) {
browser.assert.fail('goToVMtraceStep fails', 'info about error', '')
done()
} else {
incr++
browser.click('#intoforward')
.perform(() => {
setTimeout(() => {
goToVMtraceStep(browser, step, incr, done)
}, 200)
})
}
})
})
}
module.exports = GoToVmTraceStep

@ -22,9 +22,10 @@ class TestFunction extends EventEmitter {
})
})
.perform((done) => {
browser.waitForElementVisible(`[data-id="block_tx${txHash}"]`)
browser.waitForElementVisible(`[data-id="block_tx${txHash}"]`, 60000)
.click(`[data-id="block_tx${txHash}"]`)
.waitForElementVisible(`*[data-id="txLoggerTable${txHash}"]`)
.waitForElementVisible(`*[data-id="txLoggerTable${txHash}"]`, 60000)
.pause(10000)
// fetch and format transaction logs as key => pair object
.elements('css selector', `*[data-shared="key_${txHash}"]`, (res) => {
Array.isArray(res.value) && res.value.forEach(function (jsonWebElement) {

@ -450,7 +450,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
}
await appManager.activatePlugin(['contentImport', 'theme', 'editor', 'fileManager', 'compilerMetadata', 'compilerArtefacts', 'network', 'web3Provider', 'offsetToLineColumnConverter'])
await appManager.activatePlugin(['mainPanel', 'menuicons'])
await appManager.activatePlugin(['mainPanel', 'menuicons', 'tabs'])
await appManager.activatePlugin(['sidePanel']) // activating host plugin separately
await appManager.activatePlugin(['home'])
await appManager.activatePlugin(['hiddenPanel', 'pluginManager', 'fileExplorers', 'settings', 'contextualListener', 'terminal', 'fetchAndCompile'])

@ -398,6 +398,15 @@ class FileManager extends Plugin {
return this._deps.config.get('currentFile')
}
closeAllFiles () {
// TODO: Only keep `this.emit` (issue#2210)
this.emit('filesAllClosed')
this.events.emit('filesAllClosed')
for (const file in this.openedFiles) {
this.closeFile(file)
}
}
closeFile (name) {
delete this.openedFiles[name]
if (!Object.keys(this.openedFiles).length) {

@ -225,7 +225,7 @@ module.exports = class Filepanel extends ViewPlugin {
/** these are called by the react component, action is already finished whent it's called */
async setWorkspace (workspace) {
this._deps.fileManager.removeTabsOf(this._deps.fileProviders.workspace)
this._deps.fileManager.closeAllFiles()
if (workspace.isLocalhost) {
this.call('manager', 'activatePlugin', 'remixd')
} else if (await this.call('manager', 'isActive', 'remixd')) {

@ -37,6 +37,11 @@ export class TabProxy extends Plugin {
this.updateImgStyles()
})
fileManager.events.on('filesAllClosed', () => {
this.call('manager', 'activatePlugin', 'home')
this._view.filetabs.active = 'home'
})
fileManager.events.on('fileRemoved', (name) => {
const workspace = this.fileManager.currentWorkspace()

@ -403,13 +403,13 @@ class SettingsUI {
if (!accounts) accounts = []
if (this.accountListCallId > callid) return
this.accountListCallId++
for (var loadedaddress in this.loadedAccounts) {
for (const loadedaddress in this.loadedAccounts) {
if (accounts.indexOf(loadedaddress) === -1) {
txOrigin.removeChild(txOrigin.querySelector('option[value="' + loadedaddress + '"]'))
delete this.loadedAccounts[loadedaddress]
}
}
for (var i in accounts) {
for (const i in accounts) {
const address = accounts[i]
if (!this.loadedAccounts[address]) {
txOrigin.appendChild(yo`<option value="${address}" >${address}</option>`)

@ -22,6 +22,7 @@ const css = csjs`
user-select: none;
}
.text:hover {
cursor: pointer;
text-decoration: underline;
}
.homeContainer {
@ -300,6 +301,11 @@ export class LandingPage extends ViewPlugin {
await this.appManager.activatePlugin('pluginManager')
this.verticalIcons.select('pluginManager')
}
const startRestoreBackupZip = async () => {
await this.appManager.activatePlugin(['restorebackupzip'])
this.verticalIcons.select('restorebackupzip')
_paq.push(['trackEvent', 'pluginManager', 'userActivate', 'restorebackupzip'])
}
const createNewFile = () => {
this.call('fileExplorers', 'createNewFile')
@ -456,7 +462,7 @@ export class LandingPage extends ViewPlugin {
)
}
const img = yo`<img class=${css.logoImg} src="assets/img/guitarRemiCroped.webp" onclick="${() => playRemi()}"></img>`
const img = yo`<img class="m-4 ${css.logoImg}" src="assets/img/guitarRemiCroped.webp" onclick="${() => playRemi()}"></img>`
const playRemi = async () => { await document.getElementById('remiAudio').play() }
// to retrieve medium posts
document.body.appendChild(yo`<script src="https://www.twilik.com/assets/retainable/rss-embed/retainable-rss-embed.js"></script>`)
@ -466,24 +472,46 @@ export class LandingPage extends ViewPlugin {
<div class="d-flex justify-content-between">
<div class="d-flex flex-column">
<div class="border-bottom d-flex justify-content-between clearfix py-3 mb-4">
<div class="mx-4 w-100">
<div class="mx-4 w-100 d-flex">
${img}
<audio id="remiAudio" muted=false src="assets/audio/remiGuitar-single-power-chord-A-minor.wav"></audio>
<div class="w-80 pl-5 ml-5">
<h5 class="mb-1">Quicklinks</h5>
<a class="${css.text} mr-1" target="__blank" href="https://medium.com/remix-ide/migrating-files-to-workspaces-8e34737c751c?source=friends_link&sk=b75cfd9093aa23c78be13cce49e4a5e8">Guide </a>for migrating the old File System
<p class="font-weight-bold mb-0 py-1">Migration tools:</p>
<li class="pl-1">
<spam class="pl-0">
<u class="${css.text} pr-1" onclick=${() => migrateWorkspace()}>Basic migration</u>
</spam>
</li>
<li class="pl-1">
<u class="${css.text} pr-1" onclick=${() => downloadFiles()}>Download all Files</u>
as a backup zip
</li>
<li class="pl-1">
<u class="${css.text} pr-1" onclick=${() => startRestoreBackupZip()}>Restore files</u>from backup zip
</li>
<p class="font-weight-bold mb-0 mt-2">Help:</p>
<dir class="d-flex flex-column mt-1 pl-0">
<a class="${css.text} mx-1" target="__blank" href="https://gitter.im/ethereum/remix">Gitter channel</a>
<a class="${css.text} mx-1" target="__blank" href="https://github.com/ethereum/remix-project/issues">Report on Github</a>
</dir>
</div>
</div>
</div>
<div class="row ${css.hpSections} mx-4" data-id="landingPageHpSections">
<div class="ml-3">
<div class="plugins mb-5">
<h4>Featured Plugins</h4>
<div class="d-flex flex-row pt-2">
${this.solEnv}
${this.learnEthEnv}
${this.solhintEnv}
${this.sourcifyEnv}
${this.debuggerEnv}
${this.moreEnv}
<h4>Featured Plugins</h4>
<div class="d-flex flex-row pt-2">
${this.solEnv}
${this.learnEthEnv}
${this.solhintEnv}
${this.sourcifyEnv}
${this.debuggerEnv}
${this.moreEnv}
</div>
</div>
</div>
<div class="d-flex">
<div class="file">
<h4>File</h4>
@ -495,22 +523,17 @@ export class LandingPage extends ViewPlugin {
<i class="mr-1 far fa-file-alt"></i>
<label class="ml-1 ${css.labelIt} ${css.bigLabelSize} ${css.text}">
Open Files
<input title="open file" type="file" onchange="${
(event) => {
event.stopPropagation()
uploadFile(event.target)
}
}" multiple />
<input title="open file" type="file" onchange="${(event) => {
event.stopPropagation()
uploadFile(event.target)
}
}" multiple />
</label>
</p>
<p class="mb-1">
<i class="far fa-hdd"></i>
<span class="ml-1 ${css.text}" onclick=${() => connectToLocalhost()}>Connect to Localhost</span>
</p>
<p class="mb-1">
<i class="mr-1 fas fa-download""></i>
<span class="ml-1 mb-1 ${css.text}" onclick=${() => downloadFiles()}>Download all Files</span>
</p>
<p class="mt-3 mb-0"><label>IMPORT FROM:</label></p>
<div class="btn-group">
<button class="btn mr-1 btn-secondary" data-id="landingPageImportFromGistButton" onclick="${() => importFromGist()}">Gist</button>
@ -529,7 +552,7 @@ export class LandingPage extends ViewPlugin {
<p class="mb-1">
<i class="mr-1 fab fa-gitter"></i>
<a class="${css.text}" target="__blank" href="https://gitter.im/ethereum/remix">Gitter channel</a>
</p>
</p>
<p class="mb-1">
${this.websiteIcon}
<a class="${css.text}" target="__blank" href="https://remix-project.org">Featuring website</a>
@ -538,10 +561,6 @@ export class LandingPage extends ViewPlugin {
<i class="fab fa-ethereum ${css.image}"></i>
<span class="${css.text}" onclick=${() => switchToPreviousVersion()}>Old experience</span>
</p>
<p>
<i class="fas fa-exclamation-triangle text-warning ${css.image}"></i>
<span class="${css.text}" onclick=${() => migrateWorkspace()}>Migrate old filesystem to workspace</span>
</p>
</div>
</div>
</div>

@ -1,6 +1,7 @@
import { Storage } from '@remix-project/remix-lib'
import { joinPath } from './lib/helper'
import yo from 'yo-yo'
const modalDialogCustom = require('./app/ui/modal-dialog-custom')
/*
Migrating the files to the BrowserFS storage instead or raw localstorage
*/
@ -53,7 +54,11 @@ const populateWorkspace = async (workspace, json, browserProvider) => {
browserProvider.createDir(joinPath(workspace, item))
await populateWorkspace(workspace, json[item].children, browserProvider)
} else {
await browserProvider.set(joinPath(workspace, item), json[item].content)
await browserProvider.set(joinPath(workspace, item), json[item].content, (err) => {
if (err && err.message) {
modalDialogCustom.alert(yo`<div>There was an error migrating your files:${err.message} <div>Please use the ‘Download all Files' action, clear the local storage and re-import your files manually or use the 'Restore files' action.</div></div>`)
}
})
}
}
}

@ -1001,7 +1001,7 @@ export const FileExplorer = (props: FileExplorerProps) => {
<div onClick={(e) => {
e.stopPropagation()
if (e && (e.target as any).getAttribute('data-id') === 'fileExplorerUploadFileuploadFile') return // we don't want to let propagate the input of type file
if (e && (e.target as any).getAttribute('data-id') === 'fileExplorerFileUpload') return // we don't want to let propagate the input of type file
let expandPath = []
if (!state.expandPath.includes(props.name)) {

@ -208,6 +208,7 @@ export const Workspace = (props: WorkspaceProps) => {
}
const onFinishDeleteWorkspace = async () => {
await props.fileManager.closeAllFiles()
const workspacesPath = props.workspace.workspacesPath
props.browser.remove(workspacesPath + '/' + state.currentWorkspace)
const name = state.currentWorkspace
@ -223,7 +224,7 @@ export const Workspace = (props: WorkspaceProps) => {
}
const setWorkspace = async (name) => {
props.setWorkspace({ name, isLocalhost: name === LOCALHOST })
await props.setWorkspace({ name, isLocalhost: name === LOCALHOST })
if (name === LOCALHOST) {
props.workspace.clearWorkspace()
} else if (name === NO_WORKSPACE) {
@ -238,8 +239,8 @@ export const Workspace = (props: WorkspaceProps) => {
}
const remixdExplorer = {
hide: () => {
if (state.currentWorkspace === LOCALHOST) setWorkspace(NO_WORKSPACE)
hide: async () => {
await setWorkspace(NO_WORKSPACE)
props.fileManager.setMode('browser')
setState(prevState => {
return { ...prevState, hideRemixdExplorer: true, loadingLocalhost: false }

@ -0,0 +1,43 @@
# Release Management
Release managers are responsible for the release management lifecycle, focusing on coordinating various aspects of production and projects into one integrated solution. They are responsible for ensuring that resources, timelines, and the overall quality of the process are all considered and accounted for.
# Steps of Release Management
## Release planning:
In this stage, release manager will elaborate a plan for the coming release.
Together with the team, the release manager will form a list of issues and PRs that should be addressed during the release.
More generally and a non negligeable part of the planning is to properly ensure that bugs, issues that weren't totally identified in the roadmap, and the roadmap issues are still being processed as they should.
## Configuring releases:
Release managers will oversee the various aspects of a project before it is due to be deployed, ensuring everyone is on track and meeting the agreed timeline.
## Quality checks:
The quality of the release needs to be reviewed before a project is officially launched.
The release manager is in charge of ensuring manual testing is properly planned and done.
Also that unit testing and e2e for new feaures have been included.
## Deployment:
After being quality checked, the project is ready to be deployed.
The release manager is still responsible for ensuring a project is rolled out smoothly and efficiently.
# Responsibilities
- Planning release windows and the overall release lifecycle.
- Managing risks that may affect release scope.
- Measure and monitor progress.
- Ensure releases are delivered within requirements.
- Manage relationships and coordinate projects.
# Miscellaneous
- Regular check for new filed issues, identify those that requires to be published (included in the release)
- In some really specific situation, it could be required to deploy intermediate releases (e.g critical bug fixes).
- Planning, refinement, retrospective meetings have to be organized by the release manager and any other required meetings.
- Release manager should feel free to implement new techniques and put their own finger print to their release, this could potentially benefit upcoming releases.
# Release Management Role
Aniket, Liana, David, Rob, Filip

@ -1,43 +1,79 @@
# Release Management
# Release process
Release managers are responsible for the release management lifecycle, focusing on coordinating various aspects of production and projects into one integrated solution. They are responsible for ensuring that resources, timelines, and the overall quality of the process are all considered and accounted for.
This document includes:
- how to publish remix libs to NPM
- how to update remix.ethereum.org
- how to update remix-alpha.ethereum.org
- how to update remix-beta.ethereum.org
- how to release remix IDE
# Steps of Release Management
## Remix libs release
- git fetch origin master
- git checkout origin/master
- git checkout -b bumpLibsVersion
- npm run publish:libs (this command uses lerna)
- commit
## Release planning:
In this stage, release manager will elaborate a plan for the coming release.
Together with the team, the release manager will form a list of issues and PRs that should be addressed during the release.
More generally and a non negligeable part of the planning is to properly ensure that bugs, issues that weren't totally identified in the roadmap, and the roadmap issues are still being processed as they should.
## Remix IDE release Part 1. First push master to beta. Feature Freeze
- git co -b remix_beta origin/remix_beta
- git reset --hard -master-commit-hash-
- git push -f origin remix_beta
## Configuring releases:
Release managers will oversee the various aspects of a project before it is due to be deployed, ensuring everyone is on track and meeting the agreed timeline.
## Testing phase
## In case of fixing bugs push PR's also to beta to include in Release
## Quality Checks:
The quality of the release needs to be reviewed before a project is officially launched.
The release manager is in charge of ensuring manual testing is properly planned and done.
Also that unit testing and e2e for new feaures have been included.
## Remix IDE release Part 2. Bump the version in beta and release
## Deployment:
After being quality checked, the project is ready to be deployed.
The release manager is still responsible for ensuring a project is rolled out smoothly and efficiently.
- git fetch origin remix_beta
- git checkout origin/remix_beta
- git checkout -b bumpVersion
- update package.json version
- remove package-lock.json version and generate a new one with `npm install`
- merge PR to origin/remix_beta
- git fetch origin remix_beta
- git checkout origin/remix_beta
- git tag v(version-number)
- git push --tags
- github-changes -o ethereum -r remix-project -a --only-pulls --use-commit-body --branch remix_beta --only-merges --between-tags previous_version...next_version
- publish a release in github using the changelog
## Remix IDE release Part 3. Bump dev branch (master)
# Responsibilities
- git fetch origin master
- git checkout origin/master
- git checkout -b bumpDevVersion
- update package.json version: bump the version and add the tag `dev` if not already present.
- remove package-lock.json version and generate a new one with `npm install`
- create a PR and merge it to origin/master
- Planning release windows and the overall release lifecycle.
- Managing risks that may affect release scope.
- Measure and monitor progress.
- Ensure releases are delivered within requirements.
- Manage relationships and coordinate projects.
## Remix IDE release Part 4. remix.ethereum.org update
# Miscellaneous
This is not strictly speaking a release. Updating the remix site is done through the Travis build:
- Regular check for new filed issues, identify those that requires to be published (included in the release)
- In some really specific situation, it could be required to deploy intermediate releases (e.g critical bug fixes).
- Planning, refinement, retrospective meetings have to be organized by the release manager and any other required meetings.
- Release manager should feel free to implement new techniques and put their own finger print to their release, this could potentially benefit upcoming releases.
- git co -b remix_live origin/remix_live
- git reset --hard -master-commit-hash- (or remix_beta-commit-hash-)
- git push -f origin remix_live
CircleCI will build automaticaly and remix.ethereum.org will be updated
# Release Management Role
## Remix IDE release Part 5. Update Zip in release
- after remix_live is updated, drop the zip (from https://github.com/ethereum/remix-live/) to the release.
Aniket, Liana, David, Rob, Filip
## Remix-ide beta release
- git fetch origin master
- git checkout origin/master
- git checkout -b bumpVersion
- update package.json version to the new version "vx.x.x-beta.1"
- remove package-lock/json version and generate a new one with `npm install`
- merge PR
- git fetch origin master
- git checkout origin/master
- git tag v(version-number) (with "vx.x.x-beta.1")
- git push --tags
- github-changes -o ethereum -r remix-project -a --only-pulls --use-commit-body --only-merges --between-tags previous_version...next_version
- publish a beta release in github using the changelog
- drop zip file to the beta release (from https://github.com/ethereum/remix-live-alpha)
## remix-alpha.ethereum.org update
remix-alpha.ethereum.org is automaticaly updated every time commits are pushed to master
Loading…
Cancel
Save