Git Product home page Git Product logo

uappkit / uapp Goto Github PK

View Code? Open in Web Editor NEW
779.0 19.0 131.0 177 KB

uapp是一款方便uni-app开发的cli工具,并通过集成electron, tauri扩展到桌面应用开发。开发者仅需维护一套代码,就能横扫所有平台。支持所有的手机端(android, ios),支持所有的电脑端(windows, mac osx, linux),支持所有的小程序,浏览器插件等等。让Web开发者能搞更多事情,会H5就够用了

License: Apache License 2.0

JavaScript 100.00%
uniapp cross-platform uapp

uapp's Issues

分享一个测试通过的 Jenkinsfile 支持 apk,wgt 构建

// 判断 manifest.json 中 versionCode 是否大于上一个版本则执行构建 apk eg:  $.versionCode2 > $.versionCode2
// 判断 git comment 中包含 [release] 则执行构建 apk eg: feat: xxxx [release]
// 判断 git comment 中包含 [wgt] 则执行构建 wgt eg: feat: xxxx [wgt]
// 构建成功之后自动更新 ctms app 版本信息
// ===============================
// >>>>>>mamifest.json 必填参数<<<<<
// $.description 更新描述
// $.versionName 版本号
// $.versionCode 版本号
// $.uapp.type 1101:android 1103:ios
// $.uapp.forceUpdate 是否强制更新
// $.uapp.diff 最大相差版本
// ================================

import groovy.json.JsonSlurper

pipeline {
    agent any

    environment  {
        APP_NAME = "ctms"
        MENTION_USERS = '"AAA BBB","小明"'
        PRODD_SERVER_HOST = credentials('example-prod-host-248')
        RELEASE_UPDATE_URL = "https://ctms.example.com/ctms/appVersion/add"
        RELEASE_USERNAME = credentials('example-admin-username')
        RELEASE_PASSWORD = credentials('example-admin-password')
    }

    stages {
        stage('release') {
            steps {
                script {
                    // 1. 获取上一个版本号
                    def previousVersion = getPreviousVersion()

                    // 2. 获取当前版本号
                    def currentVersion = getCurrentVersion()

                    echo "Previous Version: ${previousVersion}"
                    echo "Current Version: ${currentVersion}"

                    // 3. 比较版本号 或者 提交信息中含有 [release] 字样
                    if (isVersionGreaterThan(currentVersion,previousVersion) || isReleaseCommit()) {
                        echo "🚀 Current version is greater than the previous version. Starting build..."
                        // 4. 执行构建
                        def buildCommand = """
                        cd android && \
                        chmod +x ./gradlew && \
                        uapp manifest ../manifest.json && \
                        uapp run build
                        """ 

                        echo "🛠️ Executing command: ${buildCommand}"

                        try {
                            def result = sh(script: buildCommand, returnStatus: true)
                            if (result == 0) {
                                echo "✅ Build successful. "
                                // 设置变量 HAS_RELEASE_OUT 为 true
                                env.HAS_RELEASE_OUT = true
                                env.RELEASE_VERSION = currentVersion
                                echo "🎉 Release version: ${env.APP_NAME} ${env.RELEASE_VERSION} ${env.HAS_RELEASE_OUT}"
                                echo "🎉 Release path: ./android/app/build/outputs/apk/release/app-release.apk"
                                
                            } else {
                                error "❌ Build failed. Exit code: $result"
                            }
                        } catch (Exception ex) {
                            error "❌ Error during build: $ex.message"
                        }
                    } else {
                        echo "⏭️ Current version is not greater than the previous version. Skipping build."
                    }
                }
            }
        }
        stage('upload') {
            when {
                // 当 HAS_RELEASE_OUT 为 true 时执行
                expression { env.HAS_RELEASE_OUT.toString() == "true" }
            }
            steps {
                script {
                    def remote = [:]
                    remote.name = "prod-server-248"
                    remote.host = env.PRODD_SERVER_HOST
                    remote.allowAnyHosts = true
                    withCredentials([usernamePassword(credentialsId: 'example-prod-server-248', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
                        remote.user = "${USERNAME}"
                        remote.password = "${PASSWORD}"
                    }

                    def latestVersion = env.RELEASE_VERSION
                    def appName = env.APP_NAME
                    if (isZipWgtCommit()) {
                        def appid = getAppid()
                        def wgtName = "${env.APP_NAME}_${latestVersion}.wgt"
                        def zipResult = zipWgt(wgtName,appid)
                        echo "📦 Wgt path: ${zipResult} ."
                        sshPut remote: remote, from: "${zipResult}", into: "/home/static/apk/${appName}/"
                        def latestUrl = "https://static.example.com/apk/$appName/$wgtName"
                        env.LATEST_URL = latestUrl
                    }else{
                        sshPut remote: remote, from: './android/app/build/outputs/apk/release/app-release.apk', into: "/home/static/apk/${appName}/${appName}_app_v${latestVersion}.apk"
                        def latestUrl = "https://static.example.com/apk/${appName}/${appName}_app_v${latestVersion}.apk"
                        env.LATEST_URL = latestUrl
                    }

                    echo "🚀 Upload successful."
                 
                }
            }
        }
        stage('config') {
            when {
                // 当 LATEST_URL 不为空字符串时执行
                expression { env.LATEST_URL != "" && env.HAS_RELEASE_OUT.toString() == "true"}
            }
            steps {
                script {
                    echo "ℹ️ Configing..."
                    def paramsJson = buildReleaseJson()
                    def url = "${env.RELEASE_UPDATE_URL}"
                    def token = loginForToken()
                    echo "ℹ️ Config params: $paramsJson"
                    echo "ℹ️ Config url: $url"
                    echo "ℹ️ Config token: $token"
                    
                    def response = httpRequest(
                        contentType: 'APPLICATION_JSON',
                        customHeaders: [
                            [name:"Content-Type", value:"application/json"],
                            [name:"Authorization",value:"Bearer $token"]
                        ],
                        httpMode: 'POST',
                        requestBody: paramsJson,
                        url: url
                    )
                    echo "ℹ️ Config done response: $response ."
                }
            }
        }
        stage('notify') {
            when {
                // 当 LATEST_URL 不为空字符串时执行
                expression { env.LATEST_URL != "" && env.HAS_RELEASE_OUT.toString() == "true" }
            }
            steps {
                script {
                    def appName = "$env.APP_NAME $env.RELEASE_VERSION"    
                    def latestUrl = "$env.LATEST_URL"    
                    def gitCommand = "git log -1 --pretty=%B"
                    def commitMessage = sh(script: gitCommand, returnStdout: true).trim()
                    
                    def message = "🚀 $appName\\n $commitMessage\\n发布成功\\n下载地址: $latestUrl"

                    def mentionUsers = "${env.MENTION_USERS}"
                    def wechatMessageCommand = "sh /home/shell/wechat-notify.sh xxx开发者通知群 text '$message' '$mentionUsers'"

                    def result = sh(script: wechatMessageCommand, returnStdout: true).trim()
                     
                    echo "🚀 Notify done result: $result ."
                }
            }
        }
    }
}

// 获取上一个版本中 manifest.json 的 versionCode
def getPreviousVersion() {
    // 使用 Git 命令获取上一个提交的版本号
    def gitCommand = "git show HEAD^:manifest.json"
    def manifestJsonContent = sh(script: gitCommand, returnStdout: true).trim()

    // 解析 manifest.json 文件内容并获取 versionCode
    def manifestJson = readJSON text: manifestJsonContent
    def previousVersionCode = manifestJson.versionCode

    return previousVersionCode.toInteger()
}


// 获取当前版本号的函数
def getCurrentVersion() {
    // 从 manifest.json 文件中读取 versionName 字段
    def manifestJson = readJSON file: 'manifest.json'
    // 转换为 number
    return manifestJson.versionCode.toInteger()
}
 
def isVersionGreaterThan(currentVersion,previousVerion) {
    return currentVersion > previousVerion
}

//  提交信息中含有 [release] 字样
def isReleaseCommit() {
    def gitCommand = "git log -1 --pretty=%B"
    def commitMessage = sh(script: gitCommand, returnStdout: true).trim()
    return commitMessage.contains("[release]")
}

def isZipWgtCommit() {
    def gitCommand = "git log -1 --pretty=%B"
    def commitMessage = sh(script: gitCommand, returnStdout: true).trim()
    return commitMessage.contains("[wgt]")
}

// 从 manifest.json 文件中读取 appid 字段
def getAppid() {
    def manifestJson = readJSON file: 'manifest.json'
    return manifestJson.appid
}

// 构建更新配置文件
def buildReleaseJson() {
    def manifestJson = readJSON file: 'manifest.json'
    def latestUrl = "${env.LATEST_URL}"    
    def postJson = [
        "diff": manifestJson.uapp.diff,
        "downloadUrl": latestUrl,
        "forceUpdate": manifestJson.uapp.forceUpdate,
        "type": manifestJson.uapp.type,
        "versionCode": manifestJson.versionCode,
        "versionInfo": manifestJson.description,
        "versionName": manifestJson.versionName
    ]

    return groovy.json.JsonOutput.toJson(postJson)
}


// 打包成 zip 压缩包并将后缀改成 wgt
def zipWgt(wgtName,appid) {
    def zipCommand = "cd ./unpackage/resources/$appid/www/ && zip -r -q -o $wgtName . && cd ../../../../"
    def zipResult = sh(script: zipCommand, returnStdout: true).trim()

    return "./unpackage/resources/${appid}/www/${wgtName}"
}


def loginForToken(){
    def url = "https://sso.example.com/sso/user/token"
    def response = httpRequest(
            httpMode: 'POST',
            contentType: 'APPLICATION_FORM',
            requestBody: "username=${env.RELEASE_USERNAME}&password=${env.RELEASE_PASSWORD}&t=MD5",
            url: url,
            customHeaders:  [
                [name:"Content-Type",value:"application/x-www-form-urlencoded"],
                [name:"Authorization",value:"Basic xxx=="],
            ]
        )
 
    def json = new JsonSlurper().parseText(response.content)
    echo "ℹ️ Login response: $json ."
    def token = json.data.access_token    

    return token    
}
 

uapp 未来开发计划 (roadmap)

  • uapp add 计划增加桌面平台 electron, tauri
  • uapp privacy 生成经常用到的《用户协议》《隐私条款》
  • uapp sdk 改变SDK 的更新方式,官方每次下载安装包太麻烦,只有少数模块变化更新
  • 增加插件模块等的管理方式,通过官方 manifest.json 规则管理。保持与在线打包兼容

我在尝试使用此工具目前遇到问题

通过npm 或者 仓库下载的后 。

  • 但我不知道如何正确使用它
  • 通过文档配置且下载了默认安卓工程(通过各种*操作尝试),可以正常打包了。

遇到问题如下:

问题1:
使用命令如下:uapp manifest sync xxxxxxx

build.gradle 中没有 manifestPlaceholders->DCLOUD_APPKEY 等属性
但是在custom.gradle找到了它 我将它手动复制过来了。

问题2:
uapp中 cli.js文件,自由项目工程编译目录定死了

src/unpackage/resources

是否可以 让用户自定义或者通过命令行参数指定。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.