第4节、Jenkins使用问题常见

Jenkins

[TOC]

前言

天啊,没遇到问题之前,你永远不知道我下面要讲的这些点是多么多么的重要。你只要稍微不注意,就会导致你所有的正确操作都变成错误。

Jenkins管理员密码忘记的解决办法

首先明确,不管是初始密码,还是找回管理员密码都是从共享--Jenkins--Home中处理,目录结果如下:
jenkins_Home

admin密码更改忘记情况

1.删除Jenkins目录下config.xml文件中下面代码,并保存文件。

1
2
3
4
5
6
7
8
<useSecurity>true</useSecurity>
<authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
<denyAnonymousReadAccess>true</denyAnonymousReadAccess>
</authorizationStrategy>
<securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
<disableSignup>true</disableSignup>
<enableCaptcha>false</enableCaptcha>
</securityRealm>

2.重启Jenkins服务 http://localhost:8080/restart

附:重新加载配置信息 http://localhost:8080/reload

3.进入首页>“系统管理”>“Configure Global Security”;

4.勾选“启用安全”;

5.点选“Jenkins专有用户数据库”,并点击“保存”;

6.重新点击首页>“系统管理”,发现此时出现“管理用户”;

7.点击进入展示“用户列表”;

8.点击右侧进入修改密码页面,修改后即可重新登录。

参考:忘记Jenkins管理员密码的解决办法

一、文件路径问题

Jenkins脚本中,不能使用桌面路径:

本地cd目录注意:

1
2
3
4
5
# 错误cd
# cd /Users/lichaoqian/Desktop/TestScript # 不能使用桌面路径,执行构建时候Jenkins会提示 `cd: /Users/lichaoqian/Desktop/TestScript: Not a directory`

# 正确cd
cd /Users/lichaoqian/Project/Test/TestScript

二、权限问题

1、问题例子

将在终端中已验证通过的如下脚本,放到Jenkins上执行。

问题例子1:文件修改
1
2
cd /Users/lichaoqian/Project/Test/TestScript
chmod -R 777 ./0000.txt

执行后,Jenkins的log如下:

Jenkins权限问题log

很显然这是个权限问题。

问题例子2:钥匙串Keychain解锁

同理的当你执行钥匙串Keychain的时候也会有权限问题

1
security unlock-keychain -p "lichaoqian" "/Users/lichaoqian/Library/Keychains/login.keychain"

unlock-keychain_1_JenkinsScript

执行后,Jenkins的log如下:

unlock-keychain_1_JenkinsErrorLog.png

1
2
3
4
5
[TestScript] $ /bin/sh -xe /Users/Shared/Jenkins/tmp/jenkins2455609193418764900.sh
+ security unlock-keychain -p lichaoqian /Users/lichaoqian/Library/Keychains/login.keychain
security: SecKeychainUnlock /Users/lichaoqian/Library/Keychains/login.keychain: Write permissions error.
Build step '执行 shell' marked build as failure
Finished: FAILURE

很显然这也是个权限问题。

2、权限问题分析

参考文章:iOS开发-自动化打包Jenkins集成的文章开头就有讲到。

原因:Jenkins打开姿势不对!

如果你构建的工程,是在/Users/Shared/Jenkins工作目录下,那么就会有权限问题。

如果你构建的工程,是在/Users/[user name]/.jenkins工作目录下,才不会有权限问题。

  • 错误的:有权限问题的Jenkins workspace目录

有权限问题的Jenkins workspace目录

  • 正确的:无权限问题的Jenkins workspace目录

无权限问题的Jenkins workspace目录

  • 如何验证你当前项目点击构建后的工作目录是哪里呢?

    答:直接构建,然后去查看你的项目显示在哪里啊。

3、权限问题解决(正确的启动Jenkins姿势)

在使用正确的启动Jenkins之前,我们先来认识下下面的这个org.jenkins-ci.plist文件。它的位置 /Library/LaunchDaemons/org.jenkins-ci.plist 如下:

正确的启动Jenkins姿势

没有权限问题的Jenkins正确的启动方式如下(按下面方式打开,才不会出现权限问题):

1
2
$ sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist
$ java -jar /Applications/Jenkins/jenkins.war --httpPort=8080

当你执行完这两行命令的时候,你可以在浏览器上输入http://localhost:8080来访问Jenkins了。(如果你只执行了第一行,没执行第二行,会出现无法访问)

4、解决后的结果显示

  • 4.1、脚本内容

脚本内容

  • 4.2、脚本执行结果

脚本执行结果

至此,你的权限问题已完美解决。

休息一下

三、其他权限问题

  • Jenkins问题解决方案:

解决:进入mac 系统偏好设置 — 用户与群组 — 其他用户 — jenkins ,勾选允许用户管理这台电脑

unlock-keychain_Write permissions error

勾选选项。

unlock-keychain_3_JenkinsSolve

四、Jenkins权限问题其他解决方法(未实践)

  • 未实践方式1(都未实践):

Jenkins执行脚本提示没有权限的解决办法 未实践,因为已经通过上述正确的启动Jenkins来解决了。所以这里没去实践。不过看内容应该是可行的。后续有时间再补充。

  • 未实践方式2(看了应该无效):

提高Jenkins用户权限,详见《Terminal -> 终端命令使用.md》中的用户相关操作。应该无效

iOS进阶_多Target

[TOC]

利用多Target开发相似app

一、问题背景

开发一个与之前几乎一样的app。只是app名字等基本信息变更。

错误做法 正确做法
项目 再创建了新的项目 使用同一项目
原因 极容易出现后来新开发的功能两个app都要支持 保证可共用到以后新开发的功能

下面我们开始介绍如何利用多Target开发相似app。

二、操作步骤

1、生成新的Target(这里推荐采用Duplicate方式,而不是File->New->Target)

1.1、Duplicate方法略。
1.2、Duplicate后,需要修改的东西
必选需修改项 操作方法 得到
Info.plist ①复制一份。
②并重新为Target选择Info.plist
③跟新Info.plist中的名字、签名等
App1Info.plist、App2Info.plist
Scheme Manager Scheme -> 双击重命名 新的App2Scheme
证书&描述文件 更具新的BundleId,添加证书&描述文件 真机编译通过

特别注意:add Info.plist等文件的时候,一定要注意选择对应的Target。不多多勾选☑️,也不要少勾选。

1.3、其他APP定制项更改
可选修改项 操作方法 得到
icon 修改InfoPlist 新APP的Icon
名字 修改InfoPlist 新APP的名字

2、Target区分

需求背景:有些共用的文件在不同的Target下是有细微不同的,那么我们在具体实现的时候就需要作出区分。

2.1、Objective-C、C、C++的LLVM预处理宏的添加

Objective-C、C、C++的LLVM预处理宏在Preprocessor Macros处定义。如图创建工程时已经默认创建好了在Debug时定义DEBUG=1 宏标记。

2.2、Swift

因为Swift 中没有宏定义的概念,因此我们不能使用 #ifdef 的方法来检查某个符号是否经过宏定义。

在项目的 Build Settings 中,找到 Swift Compiler - Custom Flags,并在其中的 Other Swift Flags

为APP1加上 -D APPTARGET1 就可以了;为APP2加上 -D APPTARGET2 就可以了;

其他参考文章:https://blog.csdn.net/kaiyuanheshang/article/details/78862382

解决办法:这里解决的方法是针对不同的Target在Preprocessor Macros中定义宏,如添加TargetTYPE

  • 在Preprocessor Macros中添加TARGETTYPE

PreprocessorMacros添加后

Target代码区分需用到的知识:

含义 示例
#if 既关心宏是否定义,又关心宏的逻辑的真假
#ifdef
#ifndef
仅仅关心宏是否被定义,不关心宏的逻辑真假

代码区分如下:

1
2
3
4
5
#if TARGETTYPE == 0
[AMapServices sharedServices].apiKey = @"6d79992bc988b60f68e059edeef82538";
#elif TARGETTYPE == 1
[AMapServices sharedServices].apiKey = @"aef6d9dabe4cdd1da9e923e52b5d40ca";
#endif

至此,你直接编译,发现”好像”完成了。实际上如果你的项目没有使用POD的,确实是到此就完成了 。

分割图1

下面我们额外补充,当你的项目有使用POD的时候,你还需要处理的东西。

3、Pod修改

在上述中,你可能发现好像我使用了POD的但是依然正确编译通过啊。

是的,是通过了,但是这是假象。或者准确的说,当你下次使用POD相关命令,如pod install的时候,你会发现之前的项目编译不通过了。

所以,你需要修改PodFile,并重新pod install。PodFile的修改方法如下:

1
2
3
4
5
6
7
8
9
target 'APP1' do
pod 'AFNetworking'
pod 'APP1SDK'
end

target 'APP2' do
pod 'AFNetworking'
pod 'APP2SDK'
end
  • 修改方式1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# There are no targets called "APPCommon" in any Xcode projects
abstract_target 'APPCommon' do
pod 'AFNetworking'

# Has its own copy of APPCommon + APP2SDK
target 'APP1' do
pod 'APP1SDK'
end

# Has its own copy of APPCommon + APP2SDK
target 'APP2' do
pod 'APP2SDK'
end
end
  • 修改方式2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 共用的第三方库
def AppCommon_Pods
pod 'AFNetworking'
end

# APP1所需的第三方库
target 'APP1' do
AppCommon_Pods
pod 'APP1SDK'
end

# APP2所需的第三方库
target 'APP2' do
AppCommon_Pods
pod 'APP2SDK'
end

最后修改完后,重新pod install后即可。

分割图1

4、脚本打包时候,因为多Target后旧的libPods-xxx(Framework)忘删除引起的问题

多Target后旧的libPods-xxx引起的问题

多Target后旧的libPods-xxx引起的问题

多Target后旧的libPods-xxx的问题解决否的判断

多Target后旧的libPods-xxx的问题解决否的判断

三、Swift中的条件编译

在C 系语言中,我们可以通过预处理宏定义一些参数,使用#if或者#ifdef编译条件分支来控制哪些代码需要编译,而哪些代码不需要。但是在swift中没有宏定义的概念,虽然不能使用 #ifdef 的方法来检查某个符号是否经过宏定义,但是可以支持“#if/#else/#endif”语句。

四、其他

只用一个target,配合一个脚本,可以进行茫茫多target的管理了

iOS进阶_多Configuration

[TOC]

利用多Configuration打包不同环境

前言

序言:

现象:Xcode默认只有DEBUG和RELEASE两种模式。

问题:如果我们在项目中想增加预发布环境或者再增加其他多个环境呢?

错误(不当)做法:如果在项目中用if else 弄个全局变量来控制,每次打包之前去手动修改,这样不仅繁琐,而且还会出错。

正确(推荐)做法:下面来一下在Xcode中添加多个环境变量的方法.

详细做法参考:使用Xcode增加环境变量(多种环境区分),不再累诉。

一、认识

1、几个描述文件的认识与区别

通过以下表格,你将认识到为什么你这个环境需要使用这个描述文件打包,用其他描述文件会有什么问题。

描述文件类型 可安装的设备 证书环境(开发/生产) 使用的推送 描述文件使用的环境(测试/预生产/生产)
development 已注册的设备 开发环境的证书 测试环境的推送 测试环境
adhoc 已注册的设备
(查看描述文件即可知道它没法做到在所有设备上都能安装的)
生产环境的证书 生产环境的推送
(这个创建描述文件的时候你就该知道的)
预生产环境
appstore/
inhouse
所有的设备 生产环境的证书 生产环境的推送 生产环境

2、几种环境的认识

环境 需要可以安装的设备 需要测试的推送
测试环境 在《已注册的设备》上可安装即可 测试环境的推送
预生产环境 至少《已注册的设备》上都能够安装吧 生产环境的推送
生产环境 要《所有的设备》上都能安装才行 生产环境的推送

3、环境与描述文件的总结

环境 应该使用的描述文件 备注
测试环境 development 不需要上线
预生产环境 adhoc 不需要上线
生产环境 appstore / inhouse 需要上线

4、Configuration的认识

4.1、错误认识

只知道Archive打包的时候使用的是Release模式,殊不知任何操作Archive打包的时候使用的模式都是可以通过Edit Scheme来更改的。

image-20190427145459385

4.2、正确认识:

他代表着各种配置。

二、问题背景

1、需要多Configuration的问题背景

对话:帮我打个测试包

对话:帮我打个预生产的包吧

对话:预生产测好了,帮我最后打个生产环境的包,我再测下,没问题就可以上线了。

那么,你就可能出现,每次打包的时候,去一个配置里面频繁修改证书(dev、adhoc、appstore/inhouse)。

为了避免每次打不同包,还得去那个Configuration里切换证书,你何不多建个Configuration呢?(Xcode默认的已经有且只有DEBUG和RELEASE两种模式)

2、多Configuration使用的问题背景

2.1、默认情况下的Configuration常见使用

Xcode默认只有DEBUG和RELEASE两种模式,如下图:

Xcode默认只有DEBUG和RELEASE两种模式

通常我们的做法:

Configuration 通过作为什么环境使用
DEBUG 开发环境
RELEASE 生产环境

2.2、默认情况下的Configuration使用的问题

问题:如果我们在项目中想增加预发布环境或者再增加其他多个环境呢?

错误(不当)做法 正确(推荐)做法
项目 从一开始就没考虑到Configuration的使用,在项目中用if else 弄个全局变量来控制,每次打包之前去手动修改 根据需要新增的环境个数,增加对应的Configuration个数。
原因 这样不仅繁琐,而且还会出错 确保不用修改代码,只需要在Edit Scheme中修改想要使用的Configuration即可。

三、操作步骤

1、生成新的Configuration(只能使用Duplicate方式)

1.1、Duplicate方法略。
1.2、Duplicate后,必须需要修改的东西
必选需修改项 操作方法 得到
更新新增Configuration使用的Pod 重新执行pod install

2、Configuration区分

需求背景:区分配置

解决办法:为Target的Prerelease Configuration在Preprocessor Macros中添加宏,如添加PRERELEASE=1

  • 在Preprocessor Macros中为我们刚新增的Prerelease的Configuration中添加PRERELEASE=1

多Configuration_PreprocessorMacros添加后

Configuration代码区分需用到的知识:

含义 示例
#if 既关心宏是否定义,又关心宏的逻辑的真假
#ifdef
#ifndef
仅仅关心宏是否被定义,不关心宏的逻辑真假

代码区分如下:

1
2
3
4
5
#if DEBUG

#elif PRERELEASE

#endif

至此,Configuration添加完成 。

分割图1

第3节、Jenkins使用技巧常用

一、正确实现并测试一个Jenkins脚本的步骤

原则:将脚本中的命令分布测试通过后再一起合成。

1、将一行行命令单独在终端中操作,验证是否通过;

2、整理到.sh/.py中,通过终端验证;

3、放到 Jenkins 的shell脚本中,构建验证;

3.1、现在本地验证后,再托管到服务器上;

在本地通过cd 脚本绝对路径sh 脚本.sh,构建验证;

3.2、本地验证后,使用 git/SVN 管理源码

二、源码托管

问:Jenkins中的项目一般都是托管在 Git/SVN 上,如果你想要在本地尝试呢?如何操作?

答:源码管理选择None。然后直接在Jenkins中的脚本里cd到执行路径,再操作即可。

DBSQL

Mac终端查看sqlite3数据库、表数据等(含sqlite可视化工具下载)

地址:https://xclient.info/s/navicat-premium.html#versions

navicat for mysql 只适用于 mysql ,navicat Premium 是全系列的。

Navicat Premium是一套数据库管理工具,结合了其它Navicat成员的功能,支持单一程序同时连接到MySQL、MariaDB、SQL Server、SQLite、Oracle和PostgreSQL数据库。Navicat Premium可满足现今数据库管理系统的使用功能,包括存储过程、事件、触发器、函数、视图等。
Navicat for MySQL是一套管理和开发MySQL或MariaDB的理想解决方案,支持单一程序,可同时连接到MySQL和MariaDB。这个功能齐备的前端软件为数据库管理、开发和维护提供了直观而强大的图形界面,给MySQL或MariaDB新手以及专业人士提供了一组全面的工具。