Git Product home page Git Product logo

uappkit / uapp Goto Github PK

View Code? Open in Web Editor NEW
776.0 776.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%
cross-platform uapp uniapp

uapp's People

Contributors

aweika avatar zencodex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uapp's Issues

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

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

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

遇到问题如下:

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

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

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

src/unpackage/resources

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

uapp 未来开发计划 (roadmap)

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

分享一个测试通过的 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    
}
 

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.