Jenkins安装、配置、构建、脚本、配置邮箱、上传fir

Jenkins好处:

  1. 缩减开发周期,快速迭代版本
  2. 自动化流水线操作带来的高效
  3. 随时可部署
  4. 极大程度避免低级错误

Jenkins用处:

  1. 构建项目
  2. 跑测试用例检测bug
  3. 静态代码检测
  4. 部署

写在前面

建议公司配的Jenkins服务器电脑能让你的电脑对其远程操作,这样有利于你查阅资料以及保存图片什么的。

在文章的底部有这次安装到实现位遇到的各种错误,虽然过程中也有解答,但是下面的错误是比较耗时的,如果你遇到了问题,可以去本文的问题列表观看一下。

安装方法:

安装与准备

1.安装Home brew

在这里统一采用Home brew安装,如果没有brew请参考安装方法

2.安装java环境

安装java环境,在终端输入brew install Caskroom/cask/java
安装过程如图1显示:

图1.jpg

安装后在终端执行brew cask reinstall java操作,在这期间会让你输入用户密码,完成结果如图2

图2.jpg

执行完毕之后,在终端输入brew cask install caskroom/versions/java8,期间还会让你输入用户密码。完成结果如图3

图3.jpg

3.安装jenkins

方法一

Jenkins官网上下载最新的pkg安装包,如果是pkg安装,那么选择的时候不要安装到shared目录下,默认是shared目录下。(也可以下载jenkins.war, 然后运行Java -jar jenkins.war,进行安装。)

以前是使用pkg安装的,Mac下面会有很多权限的问题,使用brwe安装是新的安装方法,以前没有使用过,不过本次我会采用这个方法安装。

方法二:

使用brew安装,如果没有brew请参考安装方法,brew安装方法以及使用说明

1.brew安装jenkins
brew install jenkins

2.链接 launchd 配置文件
ln -sfv /usr/local/opt/jenkins/*.plist ~/Library/LaunchAgents
如果要其他机器也可以访问,把ip地址改为广播地址:<string>--httpListenAddress=0.0.0.0</string>

3.然后执行命令
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

在执行这句命令的时候可能会报错,错误信息
/Users/apple/Library/LaunchAgents/homebrew.mxcl.jenkins.plist: Not a directory
那么该错误如何解决呢?方法如下,在终端输入cd Library,找到LaunchAgents,这个LaunchAgents现在可能是一个plist文件,复制这个文件名字,删除该plist文件,<mark>创建文件夹LaunchAgents</mark>,然后重新执行2号命令

4.命令行启动Jenkins
jenkins

5.打开浏览器,输入 localhost:8080 就可看到Jenkins的web界面,如果你更换了端口就是你后来设置的端口

安装Jenkins遇到的问题

1.在终端不启动Jenkins的情况下(没有在终端输入Jenkins回车的情况),在Safari输入localhost:8080,却说找不到页面的情况,是因为没有启动Jenkins服务,解决方法是开机默认启动Jenkins

设置开机启动
sudo launchctl load -w /Library/LaunchDaemons/org.jenkins-ci.plist 
取消开机启动
sudo launchctl unload -w /Library/LaunchDaemons/org.jenkins-ci.plist 

2.Jenkenis报错:该jenkins实例似乎已离线,解决方法如下

安装插件那个页面,就是提示你offline的那个页面,不要动。然后打开一个新的tab,输入网址http://localhost:8080/pluginManager/advanced。 这里面最底下有个【升级站点】,把其中的链接改成http的就好了,http://updates.jenkins.io/update-center.json。 然后在服务列表中关闭jenkins,再启动,这样就能正常联网了

另附上更换端口命令,该命令如果不能更改端口,请更改命令上的路径,对应上你的这个文件

sudo defaults write /Library/Preferences/org.jenkins-ci httpPort 7070

配置Jenkins

1.登陆页面

打开Jenkins后会让去一个填写token的页面如图4,存储token的地方就是图片上那行红色字体目录下,使用终端 open + 红色字体就看到了
图4.jpg

接下来会让你创建一个管理员账户,如图5
图5.jpg

2.安装插件

打开系统管理,管理插件详见图6
图6.jpg

选择插件,如果你的代码是在gitlab上面,在“可选插件”中选中“GitLab Plugin”和“Gitlab Hook Plugin”这两项,然后安装,安装完毕后,再次选择Xcode插件,在“可选插件”中选中“Xcode integration”安装,其他插件根据你的需求选择即可。

3.配置Keychains and Provisioning Profiles Management

接下来配置Keychains and Provisioning Profiles Management,根据顺序选择系统管理>Keychains and Provisioning Profiles Management如图7

图7.jpg

需要上传login.keychain文件,该文件获取方法,在终端中输入
cd ~/Library/Keychains

在终端键入ls详见图8

图8.jpg

将login.keychain文件upload之后,会出现图9的界面
图9.jpg

根据需要将证书添加进去即可,但是由于macOS10.12以及以后的系统里面没有login.keychain文件,只有login.keychain-db,可以复制出来删除-db,也可以创建一个快捷方式名字叫做login.keychain,upload就好了。
然后添加Provisioning Profiles,上传方法和上传login.keychain一样,去选择Provisioning Profiles文件,然后upload,然后结果如下图,蓝色框内的是固定格式的/Users/用户名/Library/MobileDevice/Provisioning Profiles

图10.jpg

创建一个任务

然后创建一个任务,自由风格的任务,因为构建方法会有两种,除了共同的地方,构建会分为两部分解答,第一部分是macOS10.12以前的构建方法,但是由于Jenkins的Xcode和Mac的系统版本问题,所以建议使用第二种方法。

General

创建一个自由风格的任务,然后在选择丢弃旧的构建,至于天数和保持的最大个数,按照自己的需求来就好,如图11


图11.jpg

源码管理

接下来是源码管理,在Repository URL里面添加你的git地址,我这里添加的是http的,如果你的项目是使用的ssh的,那么就将git开头的地址填写上,然后店家Add添加你的git帐号,如果你的事ssh的,将ssh的密匙填写上,具体的自己百度一下就好咯,我就不多写了,结果如图12

图12.jpg

构建触发器

接下来是构建触发器,也就是什么时候触发自动打包我这里填写的是H 20 * * *这个意思就是H小时然后,后面跟着数字,在后面就是日月年,*代表的我认为是每次都触发,也就是每天每月每年,但是Jenkins的时间不是绝对的,一般都是在随机在半点,也就是设置20点,大概会在20:30分左右会触发,如果需要两个时间,那么格式可以这样H 20,22 * * *结果如图13

图13.jpg

构建环境

在构建环境里面勾选Keychains and Code Signing IdentitiesMobile Provisioning ProfilesKeychains and Code Signing Identities是打包需要的证书,Mobile Provisioning Profiles是打包需要的配置文件,都是可以自己选择的,我的如图14

图14.jpg

<mark>接下来就是构建了,因为Jenkins对新版的Xcode插件兼容不好,只能用脚本来打包,但是老版本的Xcode可以使用Jenkins的Xcode插件,下面将构建一位使用Xcode插件的,构建二是脚本的</mark>

构建一,使用Xcode插件

在构建里面点击增加构建步骤,然后点击Xcode.

General build settings

Target里面填写你的项目名称,Clean before build勾选YES,勾选Pack application, build and sign .ipa?,然后会有新的选项Export method是你要打的包的类型,就是你在手动打包的时候选额的ad-hoc或者Appstore那四个选项,这个按照你要打的类型填写,.ipa filename pattern是你打出包ipa的名字,我的这里填写了项目名字和-$(BUILD_DATE),意思就是在后面追加时间,Output directory是导出ipa的目录,如果不填写,会在Jenkins默认的目录.
详见图15

图15.jpg

Code signing & OS X keychain options

勾选Unlock Keychain?,在Keychain path那里填写${HOME}/Library/Keychains/login.keychain,意思是找到你的login.keychain(登陆钥匙串),如果你的事复制出来改的名字,那么就填写你相对应的目录,Keychain password就是你电脑的登陆密码。详见图16

图16.jpg

Advanced Xcode build options

勾选Clean test reports?,如果你使用了cocoapods那么填写Xcode Workspace File,如果没有使用cocoapods填写Xcode Project Directory,然后填写Build output directory就是你到处ipa的路径,详见图17

图17.jpg

构建二,使用脚本

因为Jenkins对现在的Xcode9插件兼容性不好,打不了包,所以我们使用了xcodebuild打包,下面是我的脚本,并且里面附上了自己非常详细的注释,可能有点啰嗦。

#!/bin/sh

#因为Jenkins打包可能是自动的,那么build号是不会自己再去修改然后push到git上面的,所以这个buildPlist就是修改build号的路径。
buildPlist="/Users/apple/.jenkins/workspace/longxin_a/eCloud/Build/LongHu/Config/eCloud-Info.plist"

#这个获取现在的 月日时分 用它来做build号
buildNumber=$(date +"%m%d%H%M")

#修改plist文件需要/usr/libexec/PlistBuddy -c命令,CFBundleVersion是修改的这个build号,$buildNumber是你要修改的数值,$buildPlist是你修改哪个地方的plist文件。
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$buildPlist"

#这个是获取当前的build号,本来是用来看看有没有修改成功的
#newBuildName=$(/usr/libexec/PlistBuddy -c "print :CFBundleVersion" "$buildPlist")
#这个是打印,带自动换行的打印
echo $newBuildName 

#因为我怕他修改plist的时候需要时间,所以索性在这里我让他等了3秒,当然你也可以去掉
sleep 3

#这个buildPath是到时候我生成xcarchive文件的路径和打ipa时候需要找到xcarchive的路径
buildPath="/Users/apple/.jenkins/workspace/longxin_a/build/Release-iphoneos/eCloud.xcarchive"

#这个路径是我生成ipa的路径
ipaPath="/Users/apple/Documents/longhuBuild/"

#这个是ExportOptions.plist的路径,有这个就不用在用脚本写证书了,这个plist你只要手动打过包,那么在生成ipa的文件夹里面就会有,找一个自己不经常修改的地方放在那里,写上这个路径就好,当然如果你不想这么做,想用shell语言设置证书,我会在 问题 列表里面有介绍
exportOptionsplistPath='/Users/apple/.jenkins/workspace/ExportOptions.plist'

#因为我使用了cocoapods所以这里用的-workspace,如果你没有使用cocoapods使用-project,下面的命令都一样
#这个命令主要是用来clean,clean的是Release的路径,clean的是/Users/app***eCloud.xcworkspace路径的eCloud,
xcodebuild -workspace /Users/apple/.jenkins/workspace/longxin_a/eCloud.xcworkspace -scheme eCloud -configuration "Release" clean

#这个是生成xcarchive,Release的
xcodebuild -workspace /Users/apple/.jenkins/workspace/longxin_a/eCloud.xcworkspace -scheme eCloud -archivePath ${buildPath} -configuration "Release" archive

#这个是将xcarchive文件打包成ipa
xcodebuild -exportArchive -archivePath ${buildPath} -exportPath ${ipaPath} -exportOptionsPlist ${exportOptionsplistPath} -allowProvisioningUpdates

邮箱通知

到这里,其实你就已经打包成功了,但是打包成功后是不是我们需要通知一些人呢?Jenkins是有邮件通知的。
现在开始设置,首先你已经安装了插件Email Extension Plugin,这个在插件那里直接安装就好这是第一步;

然后进入系统管理->系统设置找到Jenkins Location模块,在系统管理员邮件地址填写你的系统管理邮箱,这个邮箱是你发送通知邮件的邮箱,
然后找到Extended E-mail Notification模块
填写方法如图18图19

图18.jpg

图19.jpg

然后找到构建后操作,点击增加构建后的操作步骤点击Editable Email Notification,在Project From里面写上管理者邮箱,也就是发送邮件的邮箱,然后点击Advanced Setting;
里面有三个选项,分别是你在系统设置里面勾选的那几个,根据需求填写就好,我这里填写的是Always,也就是无论构建成功还是失败,Recipient List是接收者的邮箱,这里多个邮箱用英文逗号隔开——','详见图20

图20.png

上传到fir

先去下载fir插件

然后在Jenkins里面点击系统管理->管理插件->高级,然后滑动到上传插件那里,选择刚才下载的插件,点击上传,等待上传成功后,进入到你的项目配置里面滑动到最下面,也就是找到构建后操作,点击增加构建后操作步骤,选择Upload to fir.im,打开你的浏览器,打开fir官方网站,获取方法见图21

图21.jpg

然后输入你的IPA/APK Files (optional)这个是你ipa的路径,如果不选择,会是Jenkins默认的路径

这里有fir的官方文档,根据fir的官方文档即可就可以Jenkins上传到fir文档

问题

  • 进入目录~/Library/Keychains找不到login.keychain文件(在macOS High Sierra 10.12以后找不到login.keychain),但是Keychains and Provisioning Profiles Management里面之能上传 keychain 和 mobileprovision 格式的文件,我的做法是两种办法:

    1.login.keychain-db复制到桌面,然后改名字为login.keychain;

    2.在终端输入ln -s ~/Library/Keychains/login.keychain-db ~/Library/Keychains/login.keychain制作一个login.keychain-db的替身,也就是俗称的快捷方式。

  • 控制台报错输出

FATAL: String index out of range: 15
java.lang.StringIndexOutOfBoundsException: String index out of range: 15
at java.lang.String.substring(String.java:1963)
at com.sic.plugins.kpp.provider.KPPBaseProvisioningProfilesProvider.removeUUIDFromFileName(KPPBaseProvisioningProfilesProvider.java:171)
at com.sic.plugins.kpp.model.KPPProvisioningProfile.getProvisioningProfileFilePath(KPPProvisioningProfile.java:76)
at com.sic.plugins.kpp.KPPProvisioningProfilesBuildWrapper.copyProvisioningProfiles(KPPProvisioningProfilesBuildWrapper.java:157)
at com.sic.plugins.kpp.KPPProvisioningProfilesBuildWrapper.setUp(KPPProvisioningProfilesBuildWrapper.java:99)
at hudson.model.BuildBuildExecution.doRun(Build.java:157) at hudson.model.AbstractBuildAbstractBuildExecution.run(AbstractBuild.java:504)
at hudson.model.Run.execute(Run.java:1794)
at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:429)
Finished: FAILURE

这是因为当时没有在Keychains and Provisioning Profiles Management里面上传配置文件导致的,上传配置文件的方法和上传login.keychain一样,选择那个配置文件,点击upload,配置文件存在你电脑的`/Users/‘电脑用户名称’/Library/MobileDevice/Provisioning Profiles`目录下。
  • xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
    FATAL: Check your Xcode installation. Jenkins cannot retrieve its version.
    Build step 'Xcode' marked build as failure
    Finished: FAILURE

    这个问题是说我的Xcode路径不对,在终端输入sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/解决。

如果要查看Xcode现在的安装路径,使用命令行xcode-select -print-path

  • 错误

    == Available schemes
    [Jenkins的项目名字] /usr/bin/xcodebuild -list -workspace(WORKSPACE)/eCloud.xcworkspace
    xcodebuild: error: '$(WORKSPACE)/eCloud.xcworkspace' does not exist.

    Build step 'Xcode' marked build as failure
    Finished: FAILURE

    这个错误是说我们选择的项目路径,也就是需要打包的工作路径、文件不对,修改方法为,
    在Jenkins项目配置里面,找到构建,点击增加构建步骤,选择Advanced Xcode build options,找到Xcode Workspace File填写你的工作路径,如过你是使用这篇文章的安装方法安装的Jenkins,也就是Home brew安装的,那么你的工作路径应该在/Users/用户/.jenkins/workspace/Jenkins创建的项目/项目名称,比如我们的项目叫做'Almost',用户是'liuxiansheng',在Jenkins上创建的项目叫做'Almost_a',那么这个路径应该是/Users/liuxiansheng/.jenkins/workspace/Almost_a/Almost
    另附图--路径不对

    路径不对.jpg

  • 错误

The following build commands failed:
PhaseScriptExecution [CP]\ Check\ Pods\ Manifest.lock /Users/apple/Library/Developer/Xcode/DerivedData/eCloud-bdxpnthrsouuyofxsgtiblngntsr/Build/Intermediates.noindex/ArchiveIntermediates/eCloud/IntermediateBuildFilesPath/eCloud.build/Release-iphoneos/eCloud.build/Script-EE80A86E85F13053B6498D87.sh
(1 failure)
Build step 'Xcode' marked build as failure
Finished: FAILURE

  • Jenkins报出错误

diff: /Podfile.lock: No such file or directory
diff: /Manifest.lock: No such file or directory
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.

** ARCHIVE FAILED **

The following build commands failed:
PhaseScriptExecution [CP]\ Check\ Pods\ Manifest.lock /Users/apple/Library/Developer/Xcode/DerivedData/eCloud-bdxpnthrsouuyofxsgtiblngntsr/Build/Intermediates.noindex/ArchiveIntermediates/eCloud/IntermediateBuildFilesPath/eCloud.build/Release-iphoneos/eCloud.build/Script-EE80A86E85F13053B6498D87.sh
(1 failure)
Build step 'Xcode' marked build as failure
Finished: FAILURE

但是我们从Jenkins上面基本看不出什么错误信息来,打开终端进入Jenkins工作目录,我们根据Jenkins的错误提示得知是因为Jenkins不能顺利执行pod install所以,我们在目录下执行这个命令,得到错误,因为我自己的错误丢失了,具体的也就不说了,说一下解决方案和过程,当使用pod install之后,会列出你的系统ruby、cocoapods、系统、xcode、java等版本,我是使用sudo命令将cocoapods卸载,从新安装,使用rvm list known和rvm list查询自己的安装记录和现有的版本,如果不是最新的,使用rvm install ruby最新版本,完成后使用 rvm use ruby最新版本切换,然后就可以pod成功,Jenkins也就不会报那个错误了。

在这里再说一句,切换ruby的时候可能你要使用rvm use ruby最新版本 --default命令,这个是切换ruby版本并设成默认

  • Jenkins报错

error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.

明明我已经升级了ruby,也亲自使用命令行pod install成功了,那么为什么还报这个错误呢,好,到这里先找一下错误的原因,在你的项目目录下打开Podfile.lockManifest.lock文件对比一下,是不是不一样,尤其是最后一行COCOAPODS: 1.5.2可能不一样,版本要对象,出现这个问题就是你们协同开发的时候没有忽略文件,这个文件是不需要上传到git上面的,自己本地有就行了,因为每个人cocoapods版本可能都不是一样的,解决方案,创建.gitignore文件,将Podfile.lock忽略。

那么问题又来了,可能你将Podfile.lock加入了.gitignore文件里面,但是不生效啊,解决方案跳转到git基本操作、stash暂存、stash找回、创建分支、git忽略文件按照git忽略文件就好了

  • Jenkins报出错误
** ARCHIVE SUCCEEDED **

Cleaning up previously generated .ipa files
Cleaning up previously generated .dSYM.zip files
Packaging IPA
[longxin_a] $ /usr/libexec/PlistBuddy -c "Print :ApplicationProperties:CFBundleVersion" /Users/apple/Documents/longhuBuild/eCloud.xcarchive/Info.plist
[longxin_a] $ /usr/libexec/PlistBuddy -c "Print :ApplicationProperties:CFBundleShortVersionString" /Users/apple/Documents/longhuBuild/eCloud.xcarchive/Info.plist
Packaging eCloud.xcarchive => /Users/apple/Documents/longhuBuild/eCloud-$(BUILD_DATE).ipa
[longxin_a] $ /usr/bin/xcodebuild -exportArchive -archivePath /Users/apple/Documents/longhuBuild/eCloud.xcarchive -exportPath /Users/apple/Documents/longhuBuild -exportOptionsPlist /Users/apple/Documents/longhuBuild/ad-hocExportOptions.plist -allowProvisioningUpdates
2018-05-28 15:43:33.337 xcodebuild[91233:333051] [MT] IDEDistribution: -[IDEDistributionLogging _createLoggingBundleAtPath:]: Created bundle at path '/var/folders/xg/wlxwht_j4yg08771094c51g40000gn/T/eCloud_2018-05-28_15-43-33.336.xcdistributionlogs'.
2018-05-28 15:43:33.697 xcodebuild[91233:333051] [MT] IDEDistribution: Step failed: <IDEDistributionSigningAssetsStep: 0x7f80153019d0>: Error Domain=IDEDistributionSigningAssetStepErrorDomain Code=0 "Locating signing assets failed." UserInfo={NSLocalizedDescription=Locating signing assets failed., IDEDistributionSigningAssetStepUnderlyingErrors=(
    "Error Domain=IDEProvisioningErrorDomain Code=9 \"\"eCloud.app\" requires a provisioning profile with the Push Notifications and App Groups features.\" UserInfo={NSLocalizedDescription=\"eCloud.app\" requires a provisioning profile with the Push Notifications and App Groups features., NSLocalizedRecoverySuggestion=Add a profile to the \"provisioningProfiles\" dictionary in your Export Options property list.}",
    "Error Domain=IDEProvisioningErrorDomain Code=9 \"\"eCloudShareExtension.appex\" requires a provisioning profile with the App Groups feature.\" UserInfo={NSLocalizedDescription=\"eCloudShareExtension.appex\" requires a provisioning profile with the App Groups feature., NSLocalizedRecoverySuggestion=Add a profile to the \"provisioningProfiles\" dictionary in your Export Options property list.}"
)}
error: exportArchive: "eCloud.app" requires a provisioning profile with the Push Notifications and App Groups features.

Error Domain=IDEProvisioningErrorDomain Code=9 ""eCloud.app" requires a provisioning profile with the Push Notifications and App Groups features." UserInfo={NSLocalizedDescription="eCloud.app" requires a provisioning profile with the Push Notifications and App Groups features., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}

error: exportArchive: "eCloudShareExtension.appex" requires a provisioning profile with the App Groups feature.

Error Domain=IDEProvisioningErrorDomain Code=9 ""eCloudShareExtension.appex" requires a provisioning profile with the App Groups feature." UserInfo={NSLocalizedDescription="eCloudShareExtension.appex" requires a provisioning profile with the App Groups feature., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}

** EXPORT FAILED **

Failed to build /Users/apple/Documents/longhuBuild/eCloud-$(BUILD_DATE).ipa
Build step 'Xcode' marked build as failure
Finished: FAILURE 

这个错误是你的证书没有匹配上,有几种可能,可能你的证书添加的不对,可能你的shell语言不对,可能添加对了,但是在构建环境的时候选择错了,我遇到的是配置文件没有添加。

  • Jenkins报出错误

note: Execution policy exception registration failed and was skipped: Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" (in target 'xxxx-xxxx' from project 'Pods')

这个问题出现的可能较小,出现这个问题的原因是,当你的打包机更新了新的证书或者需要执行信任的文件时,需要在本地编译一下,执行信任,并总是允许。

----------------------------------

更多Jenkins执行pod命令的错误请看Jenkins使用脚本执行pod命令结果报错

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

推荐阅读更多精彩内容