iOS Jenkins自动打包配置全流程(2020年版 上传蒲公英+钉钉通知)

强烈建议一定要在网络好的情况下配置,并且最好能上外网,不然折磨死你!

为什么写这篇文章了,因为到目前为止我还没看到一篇完善靠谱的iOS Jenkins配置文章。

首先我这里安装配置Jenkins都是使用Homebrew
Homebrew是一款Mac OS平台下的软件包管理工具. 官网这里 Homebrew

安装以及操作步骤

  • 1.安装Homebrew
  • 2.使用Homebrew安装Jenkins
  • 3.安装Jenkins插件
  • 4.配置证书
  • 5.创建项目配置
  • 6.脚本配置
  • 7.项目打包
1.1 安装Homebrew,在终端运行以下指令安装
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

安装成功后显示

==> Installation successful!

==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
https://docs.brew.sh/Analytics
No analytics data has been sent yet (or will be during this `install` run).

==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
https://github.com/Homebrew/brew#donations

==> Next steps:
- Run `brew help` to get started
- Further documentation: 
 [https://docs.brew.sh](https://docs.brew.sh)

执行 brew -v 来查看安装版本

brew -v

显示如下则说明Homebrew安装成功

Homebrew 2.5.9-48-gf2d46ef

Homebrew/homebrew-core (git revision cb8d; last commit 2020-11-11)

edison@192 ~ % 

如果已经安装的则建议更新一下Homebrew,运行以下指令更新

brew update
2.1 通过Homebrew安装Jenkins

这里需要注意:
因为安装Jenkins需要依赖jdk,所以当我们用最新的Homebrew来安装Jenkins时会默认先安装 jdk 11版本
来源看这里 https://formulae.brew.sh/formula/jenkins

但是如果我们的项目是在gitlab上开发,那么我们在Jenkins里需要安装gitlab相关插件,gitlab需要依赖ruby-runtime。但是目前ruby-runtime是不支持jdk 11的。

这就是为什么你按照其他的教程来安装Jenkins时,教程里告诉你需要先安装jdk,然后你安装jdk 8的版本后,再用Homebrew来安装Jenkins时,结果在安装gitlab插件时,安装ruby-runtime一直显示错误

java.lang.RuntimeException: unsupported Java version: 11 

所以你以为自己安装了jdk 8,其实Homebrew已经重新下载了一份jdk 11文件,并和Jenkins形成了依赖关系。
说了这么多,怎么解决呢?

在你已经安装Homebrew的情况下,并且还没安装Jenkins时,先全局搜索Jenkins,找到如下两个文件

#3 of Mac Rlme #7.png

这两个文件是你安装Jenkins时配置jdk的文件。
把里面openjdk@11 改成openjdk@8
java_version: “11” 改成java_version: “8”

rb jenkins-Its.rb.png

这样一改那么你在下载Jenkins时就会默认下载jdk 8,注意两个文件都要改好后保存。

接下来安装Jenkins,终端执行命令安装Jenkins

brew install jenkins-lts

安装完成后会出现

==> jenkins-lts
Note: When using launchctl the port will be 8080.
To have launchd start jenkins-lts now and restart at login:
brew services start jenkins-lts
Or, if you don't want/need a background service you can just run:
 jenkins-lts

安装完成后启动Jenkins

brew services start jenkins-lts

注意我们这里的jenkins-lts就相当于Jenkins命令,这是官方提供的一种安装方式
所以当你用jenkins-lts命令安装后,执行Jenkins命令就无效
官网这里 https://www.jenkins.io/download/lts/macos/
有些博客上是写Jenkins来启动服务 (在这里就是jenkins-lts命令了)

但是直接用Jenkins命令启动服务,这样就会导致你每次重启浏览器都要执行这个命令,不然就会报你的登录名和密码错误。

所以建议使用brew services start jenkins-lts来启动Jenkins服务,这样不必每次都要执行命令来启动Jenkins

启动Jenkins后再浏览器输入以下地址

http://localhost:8080

打开之后就会出现


#41 Jenkins.png

此时说明Jenkins已经安装并且启动成功

然后通过以下地址找到密码文件initialAdminPassword
注意这里可能因为个人电脑配置而导致路径差异,要以上图中的路径为依据

/Users/edison/.jenkins/secrets/initialAdminPassword

用文本软件打开initialAdminPassword文件把密码输入,点击继续

2.2 安装推荐的插件

如果正常进入此页面 点击安装推荐的插件

ETE X Jenkins.png

此时如果出现Jenkins离线,则是网络问题导致,这个自己想办法解决网络问题

一定要把所有软件安装成功才进行下一步,如果安装失败点击重试。

SSH Credentials.png
3.1安装自己需要的插件

在首页点击Manage Jenkins->System Configuration->Manage Plugins ->可选插件
然后搜索以下列出的插件安装

  • GitLab Plugin 因为项目代码是部署在gitlab上,所以需要安装
  • Gitlab Hook Plugin
  • Xcode integration
  • Keychains and Provisioning Profiles Management 配置证书
  • DingTalk 打包成功通知群里测试
  • Git Parameter Plug-In 配置打包多个分支
4.1配置证书

由于打包需要手动配置证书,所以这里需要上传KeychainsProvisioning描述文件两个文件
在首页点击Manage Jenkins->Uncategorized->Keychains and Provisioning Profiles Management
注意在页面最底部

配置钥匙串和描述文件这里需要注意一下

很多人估计在这里会被坑到,这个应该也是Jenkins页面设计的一个缺陷。
那就是大家点击选取login.keychain之后,然后点击upload。此时钥匙串keychain是上传成功了。
但是Provisioning描述文件就没有去选取和upload上传。
我想应该是大家看到选取上传按钮只有一个,觉得选取上传按钮和对应的文件是一一对应的。
也就是会顾虑到我在同一个地方再上传Provisioning文件会覆盖掉之前的login.keychain文件,也就是之前的文件会被丢失。

但是请注意,你点击upload之后文件已经保存了。所以这里需要在同一个地方上传两个文件没问题。

image.png
4.2 上传Keychains文件

点击 选取文件 找到login.keychain这个文件

login.keychain地址

/Users/louxunmac/Library/Keychains 

注意由于系统版本升级现在没有login.keychain这个文件,取而代之的是login.keychain-db文件。
所以我们需要在同一个文件夹下拷贝一份login.keychain-db文件,然后改名成login.keychain文件
选取login.keychain之后然后点击上传upload

然后Keychains这里还有Identities->Code Signing Identity这里需要填写下,
在钥匙串里找到开发环境的证书copy证书名字然后填写到Code Signing Identity输入框里

image.png

到此keychain配置完成

4.3 上传Provisioning Profiles描述文件

Provisioning描述文件 地址

/Users/louxunmac/Library/MobileDevice/Provisioning Profiles

因为我的Jenkins打包是用的开发环境证书。所以这里只需要用到开发环境的Provisioning描述文件
如果用发布证书打包,那么别人是安装不了的。发布证书打包唯一的安装渠道是走app store
还是重复刚才配置keychain的上传步骤,点击选取开发环境Provisioning描述文件
这个地址里面可能会有多个描述文件,所以你要选择你此时在Xcode里正在使用的开发环境Provisioning描述文件
选取上传成功后然后在Provisioning Profiles Directory Path里填写Provisioning地址

到此Provisioning配置完成

最后点击save保存

至于最后判断这两项是否都配置完成可以参照我的截图

到现在Jenkins的配置告一段落。

5.1创建项目

接下来是创建一个item,即创建一个项目
这里需要注意一点,这里的项目名字一定是你的APP里 product name,否则打包时就会报路径出错导致打包失败
实在不清楚就在Xcode build setting里搜索 product name

image.png

然后选择第一个自由风格,点击确定。项目创建完毕。

5.2项目配置

5.2.1 代码打包分支配置

点击项目的配置即可进入配置页面 ,找到并勾选 This project is parameterized
由于Git Parameter插件已经安装,所以点击添加参数选中Git Parameter
然后名称写branchName , 参数类型选择 分支或标签,默认值填写origin/master ,如图

image.png
image.png

5.2.2 项目代码地址配置

源码管理里选中git,Repository URL这里填写你的git项目仓库地址,Credentials里这里相当于配置git权限

指定分支填写$branchName ,如图:

image.png

Credentials配置

点击添加Jenkins,默认进来应该就是domain是全局凭据,类型是username with password,范围是全局
那就按照默认的来配置,如果不是也最好改一下。
用户名这里填写git账号的用户名,然后填写密码,ID就是gitUser ID
这里填写完点击添加如果没有报红就说明配置成功,不用怀疑了。就如上图所示

image.png
估计很多人在这个时候会忘记自己git账号和密码,也不知道那个ID怎么填?然后也不好意思或者暂时不知道找谁拿回账号密码

因为git账号我们只需要输入一次就行,既然只需要输入一次,那么他肯定就会保存在本地。
所以只需要找到他就行

如果你是用Sourcetree,那么点击偏好设置->高级,如下图
找到主机名称,这个主机名称就是你的git项目仓库地址,用户名就是你的git账号
这里有,说明你是登录成功状态。

image.png

打开钥匙串,如下图在密码里根据你的主机名账户名找到对应的一行,然后选中,鼠标右键,复制密码
或者选中,右键点击显示简介,查看密码。

image.png

到此你的账户名和密码都已经找到了,还差一个ID
此时可以在浏览器输入那个主机名称的ip地址,然后输入账户名和密码验证下。
登入成功说明git账号密码都是对的。
然后网页最右上角点击进入setting,此时setting里面那个user ID就找到了。

image.png
image.png

5.2.3设置debugrelease 模式

点击添加参数选择choice parmaeter,然后按照下图配置就行。

image.png
image.png

5.2.4 KeychainsProvisioning配置

由于之前安装配置过Keychains and Provisioning Profiles Management,这里直接勾选,选择就行。完成

image.png

5.2.5钉钉机器人添加配置
在你当前的工作群里 智能群助手里添加机器人。
这里需要注意两点
0.1 Webhook 这个钉钉默认分配的,这个地址我们到时候要加在脚本里
0.2 安全设置,由于目前Jenkins里的插件只支持ip设置,所以这里我们先输入配置一个ip地址。
输入命令行

nslookup  localhost  
image.png

输出显示 把最后一行Address ip地址输入点击完成。至此钉钉机器人添加完成。

Server:     202.96.134.133
Address:    202.96.134.133#53

Name:   localhost
Address: 127.0.0.1

接下来是配置Jenkins钉钉机器人

点击Manage Jenkins->System Configuration->configure system 找到钉钉
这里需要勾选通知时机,看个人情况勾选。
webhook填写:钉钉群里添加的机器人里分配的webhook
ip:钉钉群里添加的机器人里配置的ip
然后点击测试,此时估计会报错,不要慌,把输入框底部提示的那个ip地址加在钉钉群里添加机器人的安全设置ip里。
然后再点击测试,提示成功。
最后别忘了保存

image.png

7.1脚本
至此,里Jenkins打包配置就差最后一步了,执行脚本配置。
对于脚本这块,因为没什么研究,所以就不多解释了。
但是需要注意几点。
7.1.1.脚本里的项目名,这个也是写的product name
脚本里有两个地方写到 项目名,就在前两行,我的项目名写的是YunDian,到时候你们自己替换成自己的就行

7.1.2 然后说说最后蒲公英和钉钉的脚本配置,就在脚本最后两段那里。
先说蒲公英,这里需要把userKeyapiKey替换成自己的,然后如果设置了下载密码就把PASSWORD也填写下
这样蒲公英的脚本配置完成

钉钉这里需要把下载链接地址https://www.pgyer.com/abc改成自己项目的下载地址,然后下载密码填上。
最后https://oapi.dingtalk.com/robot/send?access_token=d7bed3f96cbbbed96ed1a39ed0018bb815aa0jeeekkekeke这里替换成自己的Webhook

## 上传蒲公英
#userKey和apiKey需要在蒲公英的账号设置中查找
userKey="6721185289b82dcc123a2c7dddjjd"
apiKey="0385141eef7d17e0f6b5725adddddd"
PASSWORD=123
MSG=`git log -1 --pretty=%B`

#蒲公英打包
curl -F "file=@${EXPORTPATHNEWIPA}" \
-F "uKey=${userKey}" \
-F "_api_key=${apiKey}" \
-F "updateDescription=${MSG}" \
-F "password=${PASSWORD}" \
http://www.pgyer.com/apiv1/app/upload


#钉钉发布通知
message="### <font color=#00BFFF>测试环境【iOS-APP】发布成功</font>\n 下载链接:https://www.pgyer.com/abc\n密码:123"
MSG_JSON='{"msgtype":"markdown","markdown":{"title":"App发布通知","text":"'${message}'"}}'
echo "${MSG_JSON}"
echo ${1}
curl 'https://oapi.dingtalk.com/robot/send?access_token=d7bed3f96cbbbed96ed1a39ed0018bb815aa0jeeekkekeke' \
        -H  'Content-Type:application/json' \
        -d  "${MSG_JSON}"

完整脚本如下,改好后直接放在构建Execute shell里面,最后保存。

image.png

## !/bin/sh
## 项目名
TARGET_NAME=YunDian
## Scheme名
SCHEME=YunDian
##=======================
## 编译类型
if [[ "${Configuration_Type}" == "Debug" ]]; then
# 测试环境
BUILD_TYPE=Debug
else
# 生产环境
BUILD_TYPE=Release
fi

## 当前目录
SORCEPATH=${WORKSPACE}
## workspace名 YunDian.xcworkspace
SPACE=${WORKSPACE}/${TARGET_NAME}.xcworkspace
##xcarchive文件的存放路径
ARCHIVEPATH=$SORCEPATH/build/$SCHEME.xcarchive
## ipa文件的存放路径
EXPORTPATH=$SORCEPATH/build/$SCHEME
## ExportOptions.plist文件的存放路径,该文件要存放在这个路径下内容如下
EXPORTOPTIONSPLIST=$SORCEPATH/build/ExportOptions.plist
## 导出后的ipa路径
EXPORTPATHIPA=$SORCEPATH/build/$SCHEME/$SCHEME.ipa

echo -e "============First Build Clean============"
## 清理缓存
## 如果工程使用的是cocoapods,则'-project %s.xcodeproj'替换为'-workspace %s.xcworkspace'
xcodebuild clean -workspace $SPACE -scheme ${SCHEME} -configuration ${BUILD_TYPE}

DELETEIPAFILE=$SORCEPATH/build/$SCHEME/*.ipa
rm -f ${DELETEIPAFILE}

echo -e "============Build Clean============"

## 输出关键信息
echo -e "  TARGET_NAME    : ${TARGET_NAME}"
echo -e "  BUILD_TYPE    : ${BUILD_TYPE}"
echo -e "  SORCEPATH    : ${SORCEPATH}"
echo -e "  ARCHIVEPATH    : ${ARCHIVEPATH}"
echo -e "  EXPORTPATH    : ${EXPORTPATH}"
echo -e "  EXPORTOPTIONSPLIST    : ${EXPORTOPTIONSPLIST}"
echo -e "============Build Archive============"

## 导出archive包
xcodebuild archive -workspace ${SPACE} -scheme ${SCHEME} -configuration ${BUILD_TYPE} -archivePath $ARCHIVEPATH
echo -e "============Build Archive Success============"

echo -e "============Export IPA============"
## 导出IPA包
xcodebuild -exportArchive -archivePath $ARCHIVEPATH -exportPath ${EXPORTPATH} -exportOptionsPlist ${EXPORTOPTIONSPLIST}
echo -e "============Export IPA SUCCESS============"

## 编译完成时间 20181030_0931
BUILD_DATE="$(date +'%Y%m%d_%H%M')"

## info.plist路径
PROJECT_INFOPLIST_PATH="${SORCEPATH}/${TARGET_NAME}/Resources/Info.plist"
## 取版本号
BUNDLESHORTVERSION=$(/usr/libexec/PlistBuddy -c "print CFBundleShortVersionString" "${PROJECT_INFOPLIST_PATH}")
## 取build值
VERSION=$(/usr/libexec/PlistBuddy -c "print CFBundleVersion" "${PROJECT_INFOPLIST_PATH}")
## ipa更名规则  项目名V版本_年月日_时分
IPANAME="${TARGET_NAME}V${BUNDLESHORTVERSION}_${BUILD_DATE}.ipa"
## 更名后ipa路径
EXPORTPATHNEWIPA=$EXPORTPATH/$IPANAME

echo -e "============Export end :${BUILD_DATE}============"
echo -e "============IPA Old Name: ${EXPORTPATHIPA}============"
echo -e "============IPA New Name: ${EXPORTPATHNEWIPA}============"

## IPA更名
cp $EXPORTPATHIPA $EXPORTPATHNEWIPA
echo -e "============Create New Name Success============"
## 删除老IPA
rm $EXPORTPATHIPA
echo -e "============Delete Old Name Success============"

echo -e "============Start Uploading============"


## 上传蒲公英
#userKey和apiKey需要在蒲公英的账号设置中查找
userKey="6721185289b82dcc123a2c7d18859fc4"
apiKey="0385141eef7d17e0f6b5725a3f22ddc0"
PASSWORD=123
MSG=`git log -1 --pretty=%B`

#蒲公英打包
curl -F "file=@${EXPORTPATHNEWIPA}" \
-F "uKey=${userKey}" \
-F "_api_key=${apiKey}" \
-F "updateDescription=${MSG}" \
-F "password=${PASSWORD}" \
http://www.pgyer.com/apiv1/app/upload


message="### <font color=#00BFFF>测试环境【iOS-楼讯云店】发布成功</font>\n 下载链接:https://www.pgyer.com/OmpT\n密码:123"
MSG_JSON='{"msgtype":"markdown","markdown":{"title":"App发布通知","text":"'${message}'"}}'
echo "${MSG_JSON}"
echo ${1}
curl 'https://oapi.dingtalk.com/robot/send?access_token=d7bed3f96cbbbed96ed1a39ed0018bb815aa076330ac554f2e025111521da8c6' \
        -H  'Content-Type:application/json' \
        -d  "${MSG_JSON}"

这样整个Jenkins配置全部完成。

但是应该不会就这么轻易打包成功。

8.1开始打包

我们点击build with parameters,选中你要构建的分支,最后点击开始构建。

image.png

如果构建成功那就不管了,做别的事去
大概率会报错,当看到如下错误The file “ExportOptions.plist” couldn’t be opened because there is no such file时,说明ExportOptions.plist这个文件不存在。再看看报错里面的路径是在/Users/louxunmac/.jenkins/workspace/yundian/build/YunDian.xcarchive里没找到。

怎么查看错误,如下图bulid history点击构建对应的tag次数,点击倒三角查看控制台输出

+ echo -e '============Build Archive Success============'
-e ============Build Archive Success============
+ echo -e '============Export IPA============'
-e ============Export IPA============
+ xcodebuild -exportArchive -archivePath /Users/louxunmac/.jenkins/workspace/yundian/build/YunDian.xcarchive -exportPath /Users/louxunmac/.jenkins/workspace/yundian/build/YunDian -exportOptionsPlist /Users/louxunmac/.jenkins/workspace/yundian/build/ExportOptions.plist
error: Couldn't load -exportOptionsPlist: The file “ExportOptions.plist” couldn’t be opened because there is no such file.

Error Domain=NSCocoaErrorDomain Code=260 "The file “ExportOptions.plist” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/Users/louxunmac/.jenkins/workspace/yundian/build/ExportOptions.plist, NSUnderlyingError=0x7fe868b13e10 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

** EXPORT FAILED **

Build step 'Execute shell' marked build as failure
Finished: FAILURE

既然没有那么我们就创建一个ExportOptions.plist文件。
如下图创建ExportOptions.plist文件

我们需要使用Xcode来构建一个开发环境包。点击Xcode->product->archive

选择development

Select a method of distribution.png

注意这里 app thinning这里选择noneadditional options 这里不要勾选 然后点击next

Development distribution options.png

最后打包成功后,拷贝一份ExportOptions.plist文件到报错的路径下面/Users/louxunmac/.jenkins/workspace/yundian/build/YunDian.xcarchive,就拷贝在build这个文件夹里

DistributionSummary.plist.png

如果出现如下错误,那就是ipa路径不对,很可能是你上一步导出的包里面ExportOptions.plist文件的问题,所以要按照如上打包打出。

+ cp /Users/louxunmac/.jenkins/workspace/yundian/build/YunDian/YunDian.ipa '/Users/louxunmac/.jenkins/workspace/yundian/build/YunDian/YunDianV$(MARKETING_VERSION)_20201111_1134.ipa'
cp: /Users/louxunmac/.jenkins/workspace/yundian/build/YunDian/YunDian.ipa: No such file or directory
Build step 'Execute shell' marked build as failure
Finished: FAILURE

基本到此打包就会成功,如果遇到其它问题可以Google 我这里暂时只能提供这些

最后配置好了 如何让其它机器访问?比如让你们公司的测试访问你的电脑打包地址来打包

1.修改ip

homebrew.mxcl.jenkins-lts.plist文件里的httpListenAddress地址127.0.0.1 改成0.0.0.0

以下两个地方都改一下

/Users/louxunmac/Library/LaunchAgents/homebrew.mxcl.jenkins-lts.plist 

/usr/local/Cellar/jenkins-lts/2.249.3/homebrew.mxcl.jenkins-lts.plist 

改好后要让环境生效

1.链接launchd 配置文件

ln -sfv /usr/local/opt/jenkins-lts/*.plist ~/Library/LaunchAgents

2.加载文件执行命令行:

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins-lts.plist

最后重启Jenkins

brew services restart jenkins-lts

这个时候用手机输入ip地址 奇迹出现了(注意把下面的ip地址替换为你本机的ip地址,如下图箭头)

`http://10.1.221.162:8080`
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容