- // ==UserScript==
- // @name Van Deploy
- // @namespace http://tampermonkey.net/
- // @version 0.2
- // @description Auto Deploy for Van!
- // @author Alexander
- // @match https://van.huolala.work/projects/835/*
- // @match https://van.huolala.work/projects/833/*
- // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
- // @grant none
- // @license MIT
- // ==/UserScript==
-
-
- (function() {
- 'use strict';
- // console.log(' van deploy is running ')
- let monitor
- const startTime = new Date().getTime()
- const sleep = (time = 1000) => new Promise(resolve => setTimeout(resolve, time));
-
-
- class DeployTask {
- constructor(config) {
- this.id = config.id // building id
- this.branch = config.branch // branch
- this.startTime = new Date().getTime()
- // this.config = config
- this.status = 'pending' // pending, success, failed, deploying , deployed, undeployed
- this.intervalID = undefined
- this.deployInterval = undefined
- this.start()
- }
-
- getDom() {
- const taskDom = Array.from(document.getElementsByTagName('strong')).find(dom => dom.innerText === this.id)
- return taskDom ? taskDom.parentNode.parentNode : null
- }
-
- async start () {
- try {
- console.log('task ', this.id, ' start')
- this.status = 'pending'
- await this.query()
- await this.queueForDeply()
- console.log('task is deploying ', this.id)
- this.status = 'deploying'
- await this.deploy()
- this.stop()
- } catch (error) {
- console.log('deploy error ', error)
- this.stop()
- }
- }
-
- async query() {
- return new Promise((resolve, reject) => {
-
- this.intervalID = setInterval(() => {
- console.log(this.id, ' building status query ')
- const dom = this.getDom()
- if (!dom) {
- return
- }
- console.log('task is pending', this.id)
- const status = dom.getElementsByClassName('anticon')[0].className.split(' ')
-
- if (status.some(classItem => ['anticon-check-circle'].includes(classItem))) {
- clearInterval(this.intervalID)
- this.status = 'success'
- resolve()
- }
- if (status.some(classItem => ['anticon-close-circle'].includes(classItem))) {
- clearInterval(this.intervalID)
- this.status = 'failed'
- reject()
- }
- }, 1000)
- })
- }
-
- async queueForDeply () {
- return new Promise((resolve, reject) => {
- console.log('queue for deploy ', this.id)
- this.deployInterval = setInterval(() => {
- if (monitor.canDeploy()) {
- clearInterval(this.deployInterval)
- resolve()
- }
- }, 500)
- })
- }
-
- async deploy() {
- const dom = this.getDom()
- let deployed = false
- if (!dom) {
- return
- }
- dom.click()
- await sleep(3000)
- document.querySelector('.publish-btn-check button').click()
- await sleep(1000)
-
- Array.from(document.getElementsByClassName('fast-publish-btn-menu')[0].getElementsByClassName('ant-menu-item-group')).forEach(envDom => {
- const envName = envDom.getElementsByClassName('ant-menu-item-group-title')[0].innerText.toLocaleLowerCase().trim()
-
- if (this.branch.includes(envName) ) {
- deployed = true
- envDom.getElementsByClassName('ant-space-item')[0].click()
- }
- // env.getElementsByClassName('ant-space-item')
- })
- if (deployed) {
- this.status = 'deployed'
- return Promise.resolve()
- }
- this.status = 'undeployed'
- return Promise.reject()
- }
-
-
- stop() {
- // deployed, failed
- console.log('task ', this.id, ' stop')
- clearInterval(this.intervalID)
- clearInterval(this.deployInterval)
- }
- }
-
-
- class DeloyMonitor {
- constructor() {
- this.tasksQueue = []
- this.intervalID = undefined
- }
-
- async getTaskNodes () {
- const parentNode = document.getElementsByClassName('task-list-sider__list')[0]
- let nodes
- if (!parentNode) {
- await sleep(50)
- nodes = await this.getTaskNodes()
- return nodes
- }
- nodes = parentNode.getElementsByClassName('task-card')
- if (!nodes || nodes.length === 0) {
- await sleep(50)
- nodes = await this.getTaskNodes()
- return nodes
- }
- return nodes
- }
-
- parseNode(node) {
- const id = node.getElementsByClassName('first-line')[0].getElementsByTagName('strong')[0].innerText
- const branch = node.getElementsByClassName('branch')[0].innerText.trim()
- const user = node.getElementsByClassName('second-line')[0].getElementsByTagName('strong')[0].innerText.split(' ')[1];
- // const status = node.className.split(' ')[1];
- // pending : anticon-sync anticon-spin
- // success : anticon-check-circle
- // failed : anticon-close-circle
- // deployed : anticon-flag
- const status = node.getElementsByClassName('anticon')[0].className.split(' ')
- // console.log('id', id, 'status', status)
- return { id, branch, user, status }
- }
-
- start () {
-
- this.intervalID = setInterval(async () => {
- console.log('deloyMonitor is running')
- const taskNodes = await this.getTaskNodes();
-
- Array.from(taskNodes).forEach(node => {
-
- const { id, branch, user, status } = this.parseNode(node)
- // add new task
- const task = this.tasksQueue.find(item => item.id === id)
- if (!task && status.some(statusClass => ['anticon-sync', 'anticon-spin'].includes(statusClass))) {
-
- const task = new DeployTask({ id, branch, user, status })
- console.log('add new task ', id , task)
- this.tasksQueue.push(task)
- }
-
- // remove when failed , deployed
- if (status.some(statusClass => ['anticon-close-circle', 'anticon-flag'].includes(statusClass))) {
- const taskIndex = this.tasksQueue.findIndex(item => item.id === id)
- taskIndex !== -1 && console.log('will remove task ', id , task, 'taskIndex', taskIndex)
- taskIndex !== -1 && this.tasksQueue.splice(taskIndex, 1)
- }
-
- // remove when success but undeployed
- if (status.some(statusClass => ['anticon-check-circle'].includes(statusClass))) {
- const taskIndex = this.tasksQueue.findIndex(item => item.id === id)
- const successTask = this.tasksQueue[taskIndex]
- successTask.status === 'undeployed' && this.tasksQueue.splice(taskIndex, 1)
- }
-
- })
- console.clear()
- console.log('at time', parseInt((new Date().getTime() - startTime) / 1000), 'tasks are ',[...this.tasksQueue])
- }, 5000)
- }
-
- stop () {
- console.log('Please press the Logout button to logout.')
- this.tasksQueue.forEach(task => task.stop())
- clearInterval(this.intervalID)
- }
- canDeploy (){
- return !this.tasksQueue.some(task => task.status === 'deploying')
- }
- }
-
- monitor = new DeloyMonitor()
- monitor.start();
-
- window.onbeforeunload = function(e) {
- monitor.stop();
- };
-
- })();