Jenkins+fastlane 統(tǒng)一打包 RN+iOS

版權(quán)聲明:本文為博主原創(chuàng)文章榛臼,轉(zhuǎn)載請附上原文出處鏈接

Jenkins+fastlane 統(tǒng)一打包 RN+iOS

Fastlane配置

iOS根目錄下,建一個fastlane文件夾响蕴,并保存
Fastfile
Appfile

Fastfile信息參考如下

fastlane_version "1.98.0"


WORKSPACE = ENV["WORKSPACE"]
IPA_SCHEME = ENV["IPA_SCHEME"]
IPA_NAME = ENV["IPA_NAME"]
IPA_BUILD = ENV["IPA_BUILD"]
IPA_CODESIGN = ENV["IPA_CODESIGN"]
IPA_PROVISION = ENV["IPA_PROVISION"]
IPA_PROVISION_SPECIFIER = ENV["IPA_PROVISION_SPECIFIER"]
IPA_BUNDLEID = ENV["IPA_BUNDLEID"]
TEST_SERVER_URL = ENV["TEST_SERVER_URL"]
TEST_SERVER_PATH = ENV["TEST_SERVER_PATH"]


IPA_ENV = ENV["IPA_ENV"]

IPA_TEAM = ENV["IPA_TEAM"]
if "#{IPA_TEAM}" != "" then
    IPA_TEAM_DEFINE = "DEVELOPMENT_TEAM=\'#{IPA_TEAM}\'"
else
    IPA_TEAM_DEFINE = ""
end




# 獲取工程屬性
def getBuildSetting(scheme, key)

    # 嘗試從工程的plist文件中查找
    plistPath = `xcodebuild -showBuildSettings -workspace ../#{WORKSPACE}.xcworkspace -scheme #{scheme} | grep INFOPLIST_FILE | awk -F '=' '{print $2}' | awk '{$1=$1;print}' | tr -d '\n'`
    value = get_info_plist_value(path: "#{plistPath}", key: "#{key}")
    
    # 查看從plist中找到的結(jié)果是否指向工程屬性
    if value
        key = /(?=\$\()[^\)]*\)/.match("#{value}")
        if ! key
            return value
        end
        
        # 重新定義工程屬性的名稱
        key = value[2,value.length-3]
    end
    
    # 如果plist中沒有查找到或指向了工程中的屬性,則從工程屬性中查找
    value = `xcodebuild -showBuildSettings -workspace ../#{WORKSPACE}.xcworkspace -scheme #{scheme} | grep \" #{key}\" | awk -F '=' '{print $2}' | awk '{$1=$1;print}' | tr -d '\n'`
    return value
end

# 生成下載用的PLIST文件
def genPlist(url, ipaName, name, version, bundleID, plistFile)

    plistContent = "<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\n"+
    "<!DOCTYPE plist PUBLIC \\\"-//Apple//DTD PLIST 1.0//EN\\\" \\\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\\">\n"+
    "<plist version=\\\"1.0\\\">\n"+
    "  <dict>\n"+
    "      <key>items</key>\n"+
    "      <array>\n"+
    "          <dict>\n"+
    "              <key>assets</key>\n"+
    "              <array>\n"+
    "                  <dict>\n"+
    "                      <key>kind</key>\n"+
    "                      <string>software-package</string>\n"+
    "                      <key>url</key>\n"+
    "                      <string>#{url}/#{ipaName}</string>\n"+
    "                  </dict>\n"+
    # "                  <dict>\n"+
    # "                      <key>kind</key>\n"+
    # "                      <string>full-size-image</string>\n"+
    # "                      <key>needs-shine</key>\n"+
    # "                      <false/>\n"+
    # "                      <key>url</key>\n"+
    # "                      <string>#{url}/full-size-image.png</string>\n"+
    # "                  </dict>\n"+
    # "                  <dict>\n"+
    # "                      <key>kind</key>\n"+
    # "                      <string>display-image</string>\n"+
    # "                      <key>needs-shine</key>\n"+
    # "                      <false/>\n"+
    # "                      <key>url</key>\n"+
    # "                      <string>#{url}/display-image.png</string>\n"+
    # "                  </dict>\n"+
    "              </array>\n"+
    "              <key>metadata</key>\n"+
    "              <dict>\n"+
    "                  <key>title</key>\n"+
    "                  <string>#{name}</string>\n"+
    "                  <key>bundle-version</key>\n"+
    "                  <string>#{version}</string>\n"+
    "                  <key>bundle-identifier</key>\n"+
    "                  <string>#{bundleID}</string>\n"+
    "                  <key>kind</key>\n"+
    "                  <string>software</string>\n"+
    "              </dict>\n"+
    "          </dict>\n"+
    "      </array>\n"+
    "  </dict>\n"+
    "</plist>"

    `echo \"#{plistContent}\" > #{plistFile}`

end

# 制作ipa
def genIPA(isTestEnv)
    `rm -rf ../build`

# 鑰匙串的路徑為 ${HOME}/Library/Keychains/  惠桃,我們需要操作的是 login.keychain-db  或者  login.keychain
#示例 security set-key-partition-list -S apple-tool:,apple: -s -k keychainPass keychainName
#具體 security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k 123456 ~/Library/Keychains/login.keychain-db


#更新 bundleID
update_app_identifier(
  xcodeproj: "./#{WORKSPACE}.xcodeproj", # Optional path to xcodeproj, will use the first .xcodeproj if not set
  plist_path: "./#{WORKSPACE}/Info.plist", # Path to info plist file, relative to xcodeproj
  app_identifier: "#{IPA_BUNDLEID}" # The App Identifier
)

#更新配置文件設(shè)置浦夷,只對打包的 scheme 進(jìn)行修改辖试,其他不動
    update_project_provisioning(
     xcodeproj: "./#{WORKSPACE}.xcodeproj",
     profile: "./profile.mobileprovision", # optional if you use sigh
     target_filter: "#{IPA_SCHEME}", # matches name or type of a target
     build_configuration: "Release",
     code_signing_identity: "#{IPA_CODESIGN}" # optionally specify the codesigning identity
    )


    gym(
        workspace: "./#{WORKSPACE}.xcworkspace",
        scheme: "#{IPA_SCHEME}",
        clean: true,
        derived_data_path: './build/',
        output_directory: './build/',
        archive_path: './build/',
        output_name: "#{IPA_SCHEME}",
        configuration: 'Release',
        codesigning_identity: "#{IPA_CODESIGN}",
        include_symbols: 'true',
        include_bitcode: 'false',
        export_xcargs: "-allowProvisioningUpdates",
    toolchain: "cn.ijiami.obf",
        export_method: "#{IPA_ENV}",
        export_options: {
        provisioningProfiles: { 
          "#{IPA_BUNDLEID}":"#{IPA_PROVISION}"
        },
      },
        xcargs: "PROVISIONING_PROFILE_SPECIFIER='#{IPA_PROVISION}' PRODUCT_BUNDLE_IDENTIFIER='#{IPA_BUNDLEID}' ENVIRONMENT_TEST='#{isTestEnv}' CURRENT_PROJECT_VERSION='#{IPA_BUILD}' PROVISIONING_PROFILE_SPECIFIER='#{IPA_PROVISION_SPECIFIER}' PRODUCT_BUNDLE_NAME='#{IPA_NAME}' #{IPA_TEAM_DEFINE}"
    )

end

# 制作framework
def genFramework(isTestEnv)

    `rm -rf ../build`
    xcodebuild(
        workspace: "../#{WORKSPACE}.xcworkspace",
        scheme: "#{FRAMEWORK_SCHEME}",
        derivedDataPath: './build/',
        archive_path: './build/',
        configuration: 'Release',
        xcargs: "CODE_SIGN_IDENTITY='#{FRAMEWORK_CODESIGN}' PROVISIONING_PROFILE='#{FRAMEWORK_PROVISION}' PRODUCT_BUNDLE_IDENTIFIER='#{FRAMEWORK_BUNDLEID}' ENVIRONMENT_TEST='#{isTestEnv}'"
    )
    `cp -r ../build/Build/Products/Release-iphoneos/#{FRAMEWORK_SCHEME}.framework ../build/`
    
end

# ipa發(fā)布到測試服務(wù)器
def uploadTestServer(isTestEnv, isAppStore, isFramework)

    # 創(chuàng)建打包目錄
    foldername = `date +%s | tr -d '\n'`
    if isFramework then
        foldername = "#{FRAMEWORK_SCHEME}_#{foldername}"
    else
        foldername = "#{IPA_SCHEME}_#{foldername}"
    end
    `mkdir ../build/#{foldername}`

    # 創(chuàng)建描述文件,一行代表一個信息:
    # 工程名稱
    # 軟件名稱
    # 版本號
    # build號
    # 創(chuàng)建時間
    # 運(yùn)行環(huán)境
    if isFramework then
        `echo '#{FRAMEWORK_SCHEME}' > ../build/#{foldername}/index.link`
        `echo '#{FRAMEWORK_SCHEME}' >> ../build/#{foldername}/index.link`
        `echo '#{FRAMEWORK_VERSION}' >> ../build/#{foldername}/index.link`
        `echo '#{FRAMEWORK_BUILD}' >> ../build/#{foldername}/index.link`
    else
        `echo '#{IPA_SCHEME}' > ../build/#{foldername}/index.link`
        `echo '#{IPA_NAME}' >> ../build/#{foldername}/index.link`
        `echo '#{IPA_VERSION}' >> ../build/#{foldername}/index.link`
        `echo '#{IPA_BUILD}' >> ../build/#{foldername}/index.link`
    end
    package_time = `date '+%Y-%m-%d %H:%M:%S' | tr -d '\n'`
    `echo '#{package_time}' >> ../build/#{foldername}/index.link`
    if isTestEnv && isAppStore then #這里是聯(lián)調(diào)
        `echo 'joinDebug' >> ../build/#{foldername}/index.link`
    elsif isTestEnv then
        `echo 'test' >> ../build/#{foldername}/index.link`
    elsif isAppStore then
        `echo 'appstore' >> ../build/#{foldername}/index.link`
    else
        `echo 'product' >> ../build/#{foldername}/index.link`
    end
    if isFramework then
        `echo 'framework' >> ../build/#{foldername}/index.link`
    else
        `echo 'application' >> ../build/#{foldername}/index.link`
    end

    # 將ipa或者framework文件復(fù)制到該目錄中
    if isFramework then
        `mv ../build/#{FRAMEWORK_SCHEME}.framework ../build/#{foldername}/`
        `cp -r ../#{FRAMEWORK_SCHEME}/#{FRAMEWORK_SCHEME}.bundle ../build/#{foldername}/`
    else
        `mv ../build/#{IPA_SCHEME}.ipa ../build/#{foldername}/d.ipa`
        genPlist("#{TEST_SERVER_URL}/#{foldername}", "d.ipa", "#{IPA_NAME}", "#{IPA_VERSION}", "#{IPA_BUNDLEID}", "../build/#{foldername}/d.plist")
    end
    
    
    `upload_app ../build/#{foldername} iPhone`

   


end

default_platform :ios

platform :ios do
    before_all do
        # 設(shè)置全局變量
        ENV['FASTLANE_XCODE_LIST_TIMEOUT'] = '600'
        if "#{IPA_NAME}" == "" then
            IPA_NAME = getBuildSetting("#{IPA_SCHEME}", 'CFBundleDisplayName')
        end
        
        IPA_VERSION = getBuildSetting("#{IPA_SCHEME}", 'CFBundleShortVersionString')

        if "#{IPA_BUILD}" == "" then
            IPA_BUILD = getBuildSetting("#{IPA_SCHEME}", 'CFBundleVersion')
        end

   
        cocoapods(
        repo_update: false
        )

    end
    
    desc "打測試包"
    lane :test do |options|
        genIPA(1)
        uploadTestServer(true, false, false)
    end

    desc "打生產(chǎn)包"
    lane :product do |options|
        genIPA(0)
        uploadTestServer(false, false, false)
    end

    desc "打appstore包"
    lane :appstore do |options|
        genIPA(0)
       
        uploadTestServer(false, true, false)
    end


  

  after_all do |lane|
    
  end

  error do |lane, exception|
    
  end
end





Appfile信息參考如下

app_identifier "" # The bundle identifier of your app
apple_id "david.yi@chinapnr.com" # Your Apple email address
team_id "Y3697NHB4K"  # Developer Portal Team ID

創(chuàng)建Jenkins項(xiàng)目

image

配置全局參數(shù)如下

image
參數(shù)名稱 參數(shù)類型 默認(rèn)值 描述 參數(shù)值 備注
RN_VERSION 字符參數(shù) RN bundle 版本號 ? 選中下方的“Trim the string”選項(xiàng)
RN_BUILD_TYPE 選項(xiàng)參數(shù) RN 打包類型(Baseline:基線包劈狐,Extra:增量包) Baseline/Extra ?
GIT_BRANCH_RN Git Parameter RN 項(xiàng)目的 git 地址 ? 1."Parameter Type" 選擇"Branch or Tag", 2."Advanced"中 "Use repository" 填入RN 項(xiàng)目git 地址
BUILD_IOS_IPA 布爾值參數(shù) 是否構(gòu)建iOS應(yīng)用 ? 如不勾選罐孝,默認(rèn)只構(gòu)建RN項(xiàng)目
GIT_BRANCH_IOS Git Parameter iOS 項(xiàng)目的 git 地址 ? 1."Parameter Type" 選擇"Branch or Tag", 2."Advanced"中 "Use repository" 填入 iOS 項(xiàng)目git 地址
IPA_EXPORT_ENV Extend choice parameter development ios 打包類型 development,app-store,ad-hoc 三種,默認(rèn)是 development ,如果打的是 appStore 包,無論選什么,都會強(qiáng)制改為 app-store
ENVIRONMENT_CHOICE 選項(xiàng)參數(shù) test 環(huán)境標(biāo)志位 test/product/preproduct/appstore 測試/生產(chǎn)/準(zhǔn)生產(chǎn)/App Store(生產(chǎn)環(huán)境)
IPA_NAME hidden parameter 應(yīng)用名稱 應(yīng)用APP顯示名稱
WORKSPACE hidden parameter 工程名稱 工程名稱
IPA_SCHEME hidden parameter 工程中要打包的目標(biāo)名稱 工程中要打包的目標(biāo)名稱
IPA_BUNDLEID hidden parameter 工程bundleID bundleID
IPA_CODESIGN_TEST hidden parameter codesign 只要不是 AppStore 肥缔,codesign 都是這一個
IPA_CODESIGN_APPSTORE hidden parameter appstore codesign appstore codesign
TEST_SERVER_URL hidden parameter http://oa2pro.chinapnr.com/mobile/CI/iPhone/ 測試服務(wù)器的地址 打包成功后應(yīng)用上傳地址
podUpdate 布爾值參數(shù) 是否要清除緩存莲兢,更新pod 除非SDK有更新,此項(xiàng)不需要勾選

如圖

image

image

image

image

image

image

image

image

image

image

image

image

源碼管理

分別設(shè)置RN與iOS的git信息


image

設(shè)置App Store賬號信息

直接選擇app store賬號

添加RN打包腳本

#打包RN包

cd "rn"

export rnPath="./ios/RNBundle" 
if [ -d "${rnPath}" ]; then
    rm -r ${rnPath}
    mkdir ${rnPath}
else
    mkdir ${rnPath}
fi

npm install

react-native bundle --entry-file index.js --bundle-output  ${rnPath}/index.ios.bundle --platform ios --assets-dest  ${rnPath} --dev false 

if [! -f "${rnPath}/index.ios.bundle"]; then
    echo "index.ios.bundle 生成失敗"
    exit 1001
else
    echo "生成成功"
fi

echo "{'rn_version':'${RN_VERSION}','rn_build':'${BUILD_NUMBER}'}" >>  ${rnPath}/rn_info.json

添加iOS打包腳本

#清pod緩存
if [ "$podUpdate" = "true" ]; then
    #是否要清除緩存续膳,更新pod
    pod cache clean --all
    pod repo update
    
fi

#打包IPA
if [ "$BUILD_IOS_IPA" = "true" ]; then
    
    if [ "$IPA_EXPORT_ENV" = "app-store" ]; then
        export IPA_CODESIGN=$IPA_CODESIGN_APPSTORE
    else
        export IPA_CODESIGN=$IPA_CODESIGN_TEST
    fi
    
    export IPA_BUNDLEID=$IPA_BUNDLEID
    export IPA_BUILD=$BUILD_NUMBER
    export IPA_ENV=$IPA_EXPORT_ENV
    
    cd "./rn/ios"
    
    export 
      
    if [ "$IPA_EXPORT_ENV" = "app-store" ]; then
    
        result=`fastlane sigh -u $FASTLANE_ID -a $IPA_BUNDLEID --app-store true -q profile.mobileprovision`
        export IPA_PROVISION=`security cms -D -i profile.mobileprovision | sed -n -e '/<key>Name/,/string>/p' | sed -n '/string>/p' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'`
    
        export IPA_PROVISION_SPECIFIER=`security cms -D -i profile.mobileprovision | sed -n -e '/<key>Name/,/string>/p' | sed -n '/string>/p' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'`
        
    elif [ "$IPA_EXPORT_ENV" = "ad-hoc" ]; then    
    
        result=`fastlane sigh -u $FASTLANE_ID -a $IPA_BUNDLEID --adhoc true -q profile.mobileprovision`
        export IPA_PROVISION=`security cms -D -i profile.mobileprovision | sed -n -e '/<key>Name/,/string>/p' | sed -n '/string>/p' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'`
    
        export IPA_PROVISION_SPECIFIER=`security cms -D -i profile.mobileprovision | sed -n -e '/<key>Name/,/string>/p' | sed -n '/string>/p' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'`
    
    elif [ "$IPA_EXPORT_ENV" = "development" ]; then    
    
        result=`fastlane sigh -u $FASTLANE_ID -a $IPA_BUNDLEID --development true -q profile.mobileprovision`
        export IPA_PROVISION=`security cms -D -i profile.mobileprovision | sed -n -e '/<key>Name/,/string>/p' | sed -n '/string>/p' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'`
    
        export IPA_PROVISION_SPECIFIER=`security cms -D -i profile.mobileprovision | sed -n -e '/<key>Name/,/string>/p' | sed -n '/string>/p' | awk -F '>' '{print $2}' | awk -F '<' '{print $1}'`
    fi
    
    
    if [ "$ENVIRONMENT_CHOICE" = "test" ]; then
        
        result=`fastlane test`
        echo 'test'
    elif [ "$ENVIRONMENT_CHOICE" = "product" ]; then
        echo 'product'
        result=`fastlane product`
    elif [ "$ENVIRONMENT_CHOICE" = "appstore" ]; then
        echo 'app_Store'
        result=`fastlane appstore`
    fi  
fi

上傳RN bundle

#壓縮RN包并上傳

cd ./rn/ios/RNBundle

echo "開始壓縮"
export RN_ZIP_NAME="${IPA_SCHEME}_v${RN_VERSION}_b${BUILD_NUMBER}_ios_${RN_BUILD_TYPE}.zip"

export RN_BUILD_TYPE=${RN_BUILD_TYPE}

zip -r "${RN_ZIP_NAME}" . -x ".*" -x "__MACOSX" ".DS_Store"


cd ../..
 # 創(chuàng)建打包目錄
 
export foldername="${IPA_SCHEME}_$(date +%s | tr -d '\n')"

mkdir ./${foldername}

    # 創(chuàng)建描述文件改艇,一行代表一個信息:
    
echo "${IPA_SCHEME}" > ./${foldername}/index.link   # 工程名稱
echo "${IPA_NAME}" >> ./${foldername}/index.link    # 軟件包名稱
echo "${RN_VERSION}" >> ./${foldername}/index.link  # 版本號
echo "${BUILD_NUMBER}" >> ./${foldername}/index.link    # build號
    
export package_time=$(date +'%Y-%m-%d %T')
echo "${package_time}" >> ./${foldername}/index.link    # 創(chuàng)建時間

if RN_BUILD_TYPE="BaseLine"; then
   echo "baseLine" >> ./${foldername}/index.link    # 基線包
else
   echo "extra" >> ./${foldername}/index.link       # 差量包
fi

echo "application" >> ./${foldername}/index.link

echo "${RN_ZIP_NAME}" >> ./${foldername}/index.link #文件夾名稱

# 上傳RN包    
mv ./ios/RNBundle/${RN_ZIP_NAME} ./${foldername}/${RN_ZIP_NAME}

upload_app ./${foldername} ReactNative_I

 # 移除文件夾
rm -rf ./${foldername}
rm -f ./"${foldername}.zip"
cd ..
rm -rf ./rn

構(gòu)建項(xiàng)目

image

構(gòu)建成功

構(gòu)建成功后根據(jù)構(gòu)建的項(xiàng)目名稱,build號下載

RN下載地址

IPA下載地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姑宽,一起剝皮案震驚了整個濱河市遣耍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炮车,老刑警劉巖舵变,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瘦穆,居然都是意外死亡纪隙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門扛或,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绵咱,“玉大人,你說我怎么就攤上這事熙兔”妫” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵住涉,是天一觀的道長麸锉。 經(jīng)常有香客問我,道長舆声,這世上最難降的妖魔是什么花沉? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮媳握,結(jié)果婚禮上碱屁,老公的妹妹穿的比我還像新娘。我一直安慰自己蛾找,他們只是感情好娩脾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著打毛,像睡著了一般晦雨。 火紅的嫁衣襯著肌膚如雪架曹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天闹瞧,我揣著相機(jī)與錄音绑雄,去河邊找鬼。 笑死奥邮,一個胖子當(dāng)著我的面吹牛万牺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播洽腺,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼脚粟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蘸朋?” 一聲冷哼從身側(cè)響起核无,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎藕坯,沒想到半個月后团南,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡炼彪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年吐根,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辐马。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡拷橘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出喜爷,到底是詐尸還是另有隱情冗疮,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布檩帐,位于F島的核電站术幔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏轿塔。R本人自食惡果不足惜特愿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一仲墨、第九天 我趴在偏房一處隱蔽的房頂上張望勾缭。 院中可真熱鬧,春花似錦目养、人聲如沸俩由。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幻梯。三九已至兜畸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碘梢,已是汗流浹背咬摇。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留煞躬,地道東北人肛鹏。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像恩沛,于是被迫代替她去往敵國和親在扰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345