鍔堣崋鏂╂锛欸itlab 閮ㄧ讲 CI 鎸佺画闆嗘垚

闃呰鐩綍锛�/p>

  • install configue gitlab-ci-multi-runner
  • restore nuget packages
  • bulid .sln
  • run unit tests
  • configue .gitlab-ci.yml
  • configue build status badge image

CI 绮惧崕鏂囩珷锛�/p>

  • 鎸佺画闆嗘垚鏄粈涔堬紵
  • 閲嶆俯澶у笀缁忓吀锛歁artin Fowler 鐨勬寔缁泦鎴�/a>

Gitlab 閮ㄧ讲 CI 鐩稿叧璧勬枡锛�/p>

  • 閰嶇疆 gitlab-ci 杩涜鎸佺画闆嗘垚
  • 浣跨敤 GitLab-CI 鏉ヨ嚜鍔ㄥ垱寤�Docker 闀滃儚
  • 鍩轰簬 gitlab 鎼缓 CI 鐜
  • 浣跨敤 gitlab 鍜�gitlab_ci 杩涜鎸佺画闆嗘垚

鎸佺画闆嗘垚锛圕ontinuous integration - CI锛夌殑浣滅敤锛氫唬鐮佸湪鎻愪氦鍒拌祫婧愬簱涔嬪墠锛岃繘琛屾瀯寤恒�鑷姩鍖栨祴璇曞拰鍙戝竷绛夌瓑锛屾垜浠瘡澶╅渶瑕佹彁浜ゅぇ閲忕殑浠g爜锛屾寔缁泦鎴愬彲浠ユ湁鏁堢殑甯姪鎴戜滑鍙戠幇浠g爜涓殑 Bug锛屽苟涓斿噺灏戜竴浜涘弽澶嶇殑宸ヤ綔绛夌瓑锛屼娇鍥㈤槦鏇村姞鏈夋晥鐨勫紑鍙戝崗浣溿�

GitLab CI 瀹樻柟浠嬬粛锛�a href="https://about.gitlab.com/gitlab-ci/" class="uri">https://about.gitlab.com/gitlab-ci/

Gitlab 鍦�8.0 浠ヤ笂鐗堟湰闆嗘垚浜�CI锛屾墍浠ユ垜浠笉闇�鍙﹀閰嶇疆涓�釜 gitlab-ci-server 鏈嶅姟鍣紝涓烘垜浠儴缃插噺灏戜簡寰堝鐨勫伐浣滐紝鐐逛釜璧烉煈嶏紒

鍏堝悙妲戒笅锛孏itlab 閮ㄧ讲 CI 鎴戝ぇ姒傝姳浜嗕竴鍛ㄧ殑鏃堕棿锛屼絾涔熷彧鏄繘琛屼簡涓�偣鐐癸紝鏈�噸瑕佺殑涓夌偣锛�code>nuget restore, bulid *.sln鍜�code>run unit tests鐜板湪鍩烘湰涓婃槸鍙互浜嗭紝鍦ㄩ儴缃茬殑杩囩▼涓紝娣辨劅鍒伴棶棰樺垎浜殑閲嶈鎬э紝閬囧埌鐨勫ぇ閲忛棶棰橈紝Google 鍩烘湰涓婃悳涓嶅埌锛屼腑鏂囩浉鍏宠祫鏂欎篃灏变笂闈㈢殑鍑犵瘒鏂囩珷锛屼絾鐪嬭繃涔嬪悗鍙戠幇閮芥槸绠�畝鍗曞崟鐨勪粙缁嶈�宸诧紝骞舵病鏈夎褰曡缁嗙殑閮ㄧ讲杩囩▼锛屾墍浠ワ紝鎴戝熀鏈笂閮芥槸鐪嬬殑 Gitlab 瀹樻柟甯姪鏂囨。锛屼絾 Gitlab 鐨勬洿鏂板緢棰戠箒锛屾墍浠ユ湁浜涘府鍔╂枃妗i兘娌¤繘琛屾洿鏂帮紝閬垮厤涓嶄簡韪╄繘涓�簺鍧戯紝閭f�涔堝姙鍛紵瑙e喅鏂瑰紡灏辨槸涓嶆柇鐨勮繘琛屽皾璇曪紝姣斿鎴戦厤缃�code>.gitlab-ci.yml鏂囦欢鐨勬椂鍊欙紝灏变笉鏂殑杩涜code commit娴嬭瘯锛堜竴鐧惧涓彁浜ゐ煒傦級锛�/p>

鍔堣崋鏂╂锛欸itlab 閮ㄧ讲 CI 鎸佺画闆嗘垚_第1张图片

骞朵笖鏈夊厛瑙佷箣鏄庣殑鎶婇棶棰樿В鍐宠繃绋嬶紝閮界敤 Issue 杩涜璁板綍浜嗮煒忥細

鍔堣崋鏂╂锛欸itlab 閮ㄧ讲 CI 鎸佺画闆嗘垚_第2张图片

涓嬮潰灏变粠涓婇潰杩欏嚑涓�Issue 杩涜灞曞紑锛屾妸姣忎釜闂鍜岃В鍐宠繃绋嬮兘鍒嗕韩鍑烘潵锛屽笇鏈涘彲浠ュ府鍔╁埌閬囧埌鐩稿悓闂鐨勫洯鍙嬨�

1. install configue gitlab-ci-multi-runner

GitLab 閮ㄧ讲 CI 鐨勭涓�灏辨槸瀹夎 gitlab-ci-multi-runner锛屼綘鍙互鎶婂畠鐞嗚В涓猴細璺�CI 鐨勬湇鍔°�

windows 瀹夎鏁欑▼锛�a href="https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/install/windows.md" class="uri">https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/install/windows.md

涓嬭浇濂�gitlab-ci-multi-runner-windows-amd64.exe 瀹夎鏂囦欢鍚庯紝灏嗗畨瑁呮枃浠舵斁鍦�code>C:\Multi-Runner涓嬶紝浠ョ鐞嗗憳鏉冮檺杩愯鍛戒护琛岋紝濡傛灉gitlab-ci-multi-runner鍛戒护鎵句笉鍒帮紝鐩存帴鐢�code>gitlab-ci-multi-runner-windows-amd64.exe鍛戒护杩愯銆�/p>

鍦�Gitlab 椤圭洰涓墦寮�Settings > Runners锛屾壘鍒�code>URL鍜�code>token锛岀瓑浼氬畨瑁呯殑鏃跺�闇�閰嶇疆銆�/p>

瀹夎閰嶇疆姝ラ锛�/p>

C:\WINDOWS\system32>cd C:\Multi-Runner

C:\Multi-Runner>gitlab-ci-multi-runner-windows-amd64.exe register
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
URL
Please enter the gitlab-ci token for this runner:
token
Please enter the gitlab-ci description for this runner:
[DESKTOP-2P9GHDD]: xishuai-ci
Please enter the gitlab-ci tags for this runner (comma separated):
dev
Registering runner... succeeded                     runner=avuSXASJ
Please enter the executor: docker-ssh, parallels, shell, ssh, virtualbox, docker+machine, docker-ssh+machine, docker:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

涓婇潰executor: shell鏄粯璁ら厤缃紝鎰忔�鏄湰鍦版墽琛岋紝涔熷彲浠ヤ娇鐢�code>ssh鍜�code>docker锛屼笉杩囬渶瑕佸鍔犱竴浜涜繙绔摼鎺ラ厤缃�

瀹屾垚鍚庯紝浼氬湪C:\Multi-Runner鐩綍涓嬶紝鐢熸垚涓�釜config.toml閰嶇疆鏂囦欢锛屾垜浠笂闈㈣緭鍏ョ殑閰嶇疆淇℃伅涔熼兘浼氬湪杩欓噷闈紝閰嶇疆璇存槑锛�a href="https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md" class="uri">https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md

鍋滄锛岃繍琛屽拰楠岃瘉鍛戒护锛�/p>

C:\Multi-Runner>gitlab-ci-multi-runner-windows-amd64.exe stop

C:\Multi-Runner>gitlab-ci-multi-runner-windows-amd64.exe start

C:\Multi-Runner>gitlab-ci-multi-runner-windows-amd64.exe verify
Verifying runner... is alive                        runner=5ae63365

濡傛灉杩愯C:\Multi-Runner>gitlab-ci-multi-runner-windows-amd64.exe start鍑虹幇閿欒锛屽垯闇�灏�code>gitlab-ci-multi-runner-windows-amd64.exe鎷疯礉涓�唤锛岄噸鍛藉悕涓�code>gitlab-ci-multi-runner.exe銆�/p>

鍙﹀锛�Gitlab 椤圭洰 Settings > Project Settings Features > Builds 閫夐」闇�鎵撳嬀銆�/p>

gitlab-ci-multi-runner 瀹夎閰嶇疆瀹屼箣鍚庯紝鎴戜滑灏卞彲浠ュ湪 Gitlab 椤圭洰 Settings > Runners 涓紝鐪嬪埌 Runners 鐨勪俊鎭簡銆�/p>

2. restore nuget packages

杩欐浠诲姟锛氫娇鐢�CI锛�nuget 杩樺師瑙e喅鏂规涓殑绋嬪簭鍖呫�

gitlab-ci-multi-runner 瀹夎閰嶇疆瀹屼箣鍚庯紝鎴戜滑杩橀渶瑕佸湪 Gitlab 椤圭洰涓坊鍔犱竴涓�code>.gitlab-ci.yml鏂囦欢锛屽畼鏂逛粙缁嶏細http://doc.gitlab.com/ee/ci/yaml/README.html

鍥犱负涓�紑濮嬫垜瀵�code>.gitlab-ci.yml閰嶇疆涓�偣閮戒笉浜嗚В锛屾墍浠ワ紝鎴戝綋鏃舵寜鐓ц繖涓暀绋�CI Quick Start锛屾坊鍔犱簡濡備笅鐨�code>.gitlab-ci.yml鏂囦欢閰嶇疆锛�/p>

before_script:
  - apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
  - ruby -v
  - which ruby
  - gem install bundler --no-ri --no-rdoc
  - bundle install --jobs $(nproc)  "${FLAGS[@]}"

rspec:
  script:
    - bundle exec rspec

rubocop:
  script:
    - bundle exec rubocop

娣诲姞濂�code>.gitlab-ci.yml鏂囦欢閰嶇疆鍚庯紝鎴戜滑灏卞彲浠ュ湪椤圭洰涓殑 Builds锛岀湅鍒版彁浜ゅ悗鐨勬瀯寤哄伐浣滀簡锛岄殢渚垮湪 Gitlab 椤圭洰涓坊鍔犱竴涓В鍐虫柟妗堬紝鐒跺悗鍐嶆坊鍔犱竴涓被搴撻」鐩紝骞朵笖浣跨敤 nuget 瀹夎涓�釜绋嬪簭鍖咃紝鏈�悗浣跨敤 git 鎻愪氦鍒�Gitlab 涓紝灏卞彲浠ョ湅鍒�Builds 鐨勮繃绋嬪拰缁撴灉浜嗭紝棣栨鎻愪氦缁撴灉濡備笅锛�/p>

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Cloning repository...
'"git"' 锟斤拷锟斤拷锟节诧拷锟斤拷锟解部锟斤拷锟筋,也锟斤拷锟角匡拷锟斤拷锟叫的筹拷锟斤拷
锟斤拷锟斤拷锟斤拷锟斤拷锟侥硷拷锟斤拷
系统锟揭诧拷锟斤拷指锟斤拷锟斤拷路锟斤拷锟斤拷
Checking out 2f82ccb0 as master...
'"git"' 锟斤拷锟斤拷锟节诧拷锟斤拷锟解部锟斤拷锟筋,也锟斤拷锟角匡拷锟斤拷锟叫的筹拷锟斤拷
锟斤拷锟斤拷锟斤拷锟斤拷锟侥硷拷锟斤拷

ERROR: Build failed: exit status 9009

杩欎釜闂鎼炰簡鎴戝緢涔咃紝鍥犱负閿欒淇℃伅涔辩爜浜嗭紝鏍规湰鎵句笉鍒扮浉鍏崇殑瑙e喅鏂规锛屽悗鏉ユ棤鎰忛棿鎼滃埌 Gitlab 涓殑涓�釜 Issue锛岄噷闈㈡彁鍒颁簡涓�釜gitlab-ci-multi-runner --debug run鍛戒护锛屾剰鎬濇槸璋冭瘯杩愯 CI锛岃繖鏍锋垜浠氨鍙互鐪嬪埌璇︾粏鐨勯敊璇俊鎭簡锛宒ebug 鐨勯敊璇俊鎭瘮杈冨锛屽苟涓斿畬鍏ㄧ湅涓嶆噦锛屼笉杩囨垜浠彲浠ラ�杩�Builds 鐪嬪埌绠�磥鐨勯敊璇棩蹇楋細

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Cloning repository...
Cloning into 'C:/Multi-Runner/builds/500c7a25/0/dev/CNBlogsCI-Sample'...
fatal: unable to access 'https://gitlab-ci-token:[email protected]/dev/CNBlogsCI-Sample.git/': error setting certificate verify locations:
  CAfile: C:\Multi-Runner\builds\500c7a25\0\dev\CNBlogsCI-Sample.tmp\GIT_SSL_CAINFO
  CApath: none
The system cannot find the path specified.
Checking out ac05d090 as master...
fatal: Not a git repository (or any of the parent directories): .git

ERROR: Build failed: exit status 128

涓婇潰閿欒鏃ュ織鐨勬剰鎬濇槸锛屾病鏈�code>git clone repository鎴愬姛锛屽苟涓旀病鏈夋潈闄愯闂紝鍚庢潵 Google 鍒颁簡涓�釜瑙e喅鏂规锛�a href="https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/1052">error setting certificate verify locations

瑙e喅鏂瑰紡锛�code>C:\Multi-Runner\config.toml鏂囦欢娣诲姞shell = 'powershell'鑺傜偣锛屾坊鍔犲湪[[runners]]鑺傜偣鍚庛�

瑙e喅瀹岃繖涓棶棰樹箣鍚庯紝鍘荤爺绌朵簡涓�code>.gitlab-ci.yml涓殑nuget restore閰嶇疆锛圙oogle 鎼滅殑锛屽お鍧戯級锛屽皢.gitlab-ci.yml鏂囦欢淇敼濡備笅锛�/p>

stages:
  - build

job:
  stage: build
  script:
  - ls
  - echo "Restoring NuGet Packages..."
  - '"C:\Users\xishuai\.dnx\packages\ClassLibrary2\2.0.0\packages\NuGet.CommandLine.2.8.5\tools\NuGet.exe" restore "src/CNBlogsCI-Sample.sln"'

commit鎻愪氦娴嬭瘯锛屽嚭鐜颁笅闈㈢殑閿欒淇℃伅锛�/p>

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
At C:\Users\xishuai\AppData\Local\Temp\build_script140243225\script.ps1:132 char:105
+ ... 0.0\packages\NuGet.CommandLine.2.8.5\tools\NuGet.exe" restore "src/CN ...
+                                                           ~~~~~~~
Unexpected token 'restore' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : UnexpectedToken


ERROR: Build failed: exit status 1

浠庨敊璇俊鎭腑鍙互鐪嬪埌锛屾病鏈夎瘑鍒�code>restore鍛戒护锛屽暐鎰忔�锛熻繖涓棶棰樺張鎼炰簡鎴戝ソ涔咃紝Google Unexpected token 'restore' in expression or statement. 鍏抽敭瀛楋紝姣涢兘鎼滀笉鍒帮紝娌″姙娉曪紝鍚庢潵鍙兘鏇存崲鍏抽敭瀛楁悳锛屼絾鎼滃埌鐨勪俊鎭嚖姣涢簾瑙掞紝鍚庢潵鍙傝�鎼滄潵鐨勮祫鏂欙紝灏�code>.gitlab-ci.yml鏀逛负锛�/p>

stages:
  - build

job:
  stage: build
  script:
  - ls
  - echo "Restoring NuGet Packages..."
  - 'call "%VS140COMNTOOLS%\vsvars32.bat"'
# - '"C:\Users\xishuai\.dnx\packages\ClassLibrary2\2.0.0\packages\NuGet.CommandLine.2.8.5\tools\NuGet.exe" restore "src\CNBlogsCI-Sample.sln"'

鎴�/p>

before_script:
  - echo "Restoring NuGet Packages..."
  - 'call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\vsvars32.bat"'

%VS140COMNTOOLS%\vsvars32.bat 鏄粈涔堥锛熶笉澶竻妤氾紝姣棤鐤戦棶锛屽張鍑虹幇浜嗛敊璇紝淇℃伅濡備笅锛�/p>

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Fetching changes...
HEAD is now at 3926803 Update .gitlab-ci.yml
From https://gitlab.com/dev/CNBlogsCI-Sample
   3926803..d8f10a7  master     -> origin/master
Checking out d8f10a7c as master...
Previous HEAD position was 3926803... Update .gitlab-ci.yml
HEAD is now at d8f10a7... Update .gitlab-ci.yml
$ ls


    Directory: C:\Multi-Runner\builds\5ae63365\0\dev\CNBlogsCI-Sample


Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
d-----         5/4/2016  02:45 PM                src                                                                   
-a----         5/4/2016  02:45 PM             89 .gitignore                                                            
-a----         5/4/2016  02:49 PM            527 .gitlab-ci.yml                                                        
$ echo "Restoring NuGet Packages..."
Restoring NuGet Packages...
$ call "%VS140COMNTOOLS%\vsvars32.bat"
call : The term 'call' is not recognized as the name of a cmdlet, function, script file, or operable program. Check 
the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\xishuai\AppData\Local\Temp\build_script250102679\script.ps1:132 char:3
+   call "%VS140COMNTOOLS%\vsvars32.bat"
+   ~~~~
    + CategoryInfo          : ObjectNotFound: (call:String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : CommandNotFoundException


ERROR: Build failed: exit status 1

涔熸槸姣棤澶寸华鐨勯敊璇紝杩欎箞鍔炲憿锛熷悗鏉ユ兂鎯�code>nuget restore濮嬬粓涓嶆垚鍔燂紝鑳戒笉鑳芥崲涓懡浠ゅ憿锛熺獊鐒舵兂鍒颁簡 ASP.NET 5锛岃繕鍘熺▼搴忓寘浣跨敤鐨勬槸dnu restore鍛戒护锛岄偅灏卞皾璇曚笅鍚э紝灏嗚В鍐虫柟妗堜腑鐨勯」鐩垹鎺夛紝鐒跺悗娣诲姞 ASP.NET 5 椤圭洰锛�code>.gitlab-ci.yml鏀逛负锛�/p>

before_script:
  - echo "Restoring NuGet Packages..."
  - dnvm use 1.0.0-beta5 -r coreclr -a x64
  - dnu restore

鍝囧锛岃繖娆$粓浜庢垚鍔熶簡锛堢獊鐒舵湁绉嶆兂鍝殑鍐插姩馃槶锛夛紝鏃ュ織淇℃伅锛�/p>

Running on DESKTOP-2P9GHDD...
Fetching changes...
HEAD is now at 33436d8 test commit
From https://gitlab.com/dev/CNBlogsCI-Sample
   33436d8..c80b2d5  master     -> origin/master
Checking out c80b2d5d as master...
Previous HEAD position was 33436d8... test commit
HEAD is now at c80b2d5... test commit
$ echo "Release build..."
Release build...
$ dnvm use 1.0.0-beta5 -r coreclr -a x64
Adding C:\Users\xishuai\.dnx\runtimes\dnx-coreclr-win-x64.1.0.0-beta5\bin to process PATH
$ dnu restore
Microsoft .NET Development Utility CoreCLR-x64-1.0.0-beta5-12103

Restoring packages for C:\Multi-Runner\builds\5ae63365\0\dev\CNBlogsCI-Sample\src\CNBlogsCI-Sample.ClassLibrary\project.json
  GET https://www.nuget.org/api/v2/
  OK https://www.nuget.org/api/v2/ 5524ms
  GET http://nuget.cnitblog.com/nuget/Default/
  OK http://nuget.cnitblog.com/nuget/Default/ 2406ms
  GET https://www.myget.org/F/aspnetvnext/api/v2/
  OK https://www.myget.org/F/aspnetvnext/api/v2/ 5225ms
  CACHE https://www.nuget.org/api/v2/
  GET https://www.myget.org/F/aspnetmaster/api/v3/index.json
  OK https://www.myget.org/F/aspnetmaster/api/v3/index.json 2938ms
  GET https://www.myget.org/F/xunit/api/v3/index.json
  OK https://www.myget.org/F/xunit/api/v3/index.json 1976ms
Writing lock file C:\Multi-Runner\builds\5ae63365\0\dev\CNBlogsCI-Sample\src\CNBlogsCI-Sample.ClassLibrary\project.lock.json
Restore complete, 18775ms elapsed

Build succeeded

铏界劧 ASP.NET 5 杩樺師绋嬪簭鍖呮垚鍔熶簡锛屼絾渚濇棫瑙e喅涓嶄簡闂鍟婏紝鍥犱负蹇呴』寰楄В鍐�code>nuget restore鐨勯棶棰橈紝鍥犱负寰堝椤圭洰閮芥病鐢�ASP.NET 5锛屾�涔堝姙鍛紵鍙堝洖鍒颁簡鍑哄彂鐐癸紝闂鑳界(姝讳汉鍟婏紝杩囩▼灏变笉鍙欒堪浜嗭紝鍚庢潵鏃犳剰闂村皢.gitlab-ci.yml鏀逛负锛�/p>

before_script:
  - echo "Restoring NuGet Packages..."
  - C:\Program Files (x86)\NuGet\nuget.exe restore src/CNBlogsCI-Sample.sln

浠旂粏鐪嬬湅鍜屼笂闈㈢殑閰嶇疆鏈変粈涔堜笉鍚岋紝鎴戞妸'"鍘绘帀浜嗭紝commit浠g爜娴嬭瘯锛屽嚭鐜颁簡涓嬮潰鍜屼竴寮�涓嶄竴鏍风殑閿欒锛堟湁鎴忎簡馃槒锛夛細

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Fetching changes...
Removing src/ClassLibrary1/bin/
Removing src/ClassLibrary1/obj/
HEAD is now at 191e7e0 test commit
From https://gitlab.com/dev/CNBlogsCI-Sample
   191e7e0..feebdef  master     -> origin/master
Checking out feebdefb as master...
Previous HEAD position was 191e7e0... test commit
HEAD is now at feebdef... test commit
$ echo "Restoring NuGet Packages..."
Restoring NuGet Packages...
$ C:\Program Files (x86)\NuGet\nuget.exe restore src/CNBlogsCI-Sample.sln
x86 : The term 'x86' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the 
spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\Users\xishuai\AppData\Local\Temp\build_script166211738\script.ps1:128 char:21
+   C:\Program Files (x86)\NuGet\nuget.exe restore src/CNBlogsCI-Sample ...
+                     ~~~
    + CategoryInfo          : ObjectNotFound: (x86:String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : CommandNotFoundException


ERROR: Build failed: exit status 1

鏍规嵁涓婇潰鐨勯敊璇棩蹇楋紝鍙互鐪嬪埌锛屽氨鏄洰褰曚腑鐨�code>x86闂锛岀劧鍚庢垜鎶婄洰褰曟敼涓�code>C:\Program Files\NuGet\nuget.exe涔嬪悗锛�code>nuget.exe鎷疯礉鍒扮浉搴旂洰褰曚笅锛夛紝杩樻槸鏈夐棶棰橈紝鐒跺悗灏辩洿鎺ユ斁鍦�code>C鐩樼洰褰曚笅锛岀粓浜�code>build鎴愬姛锛堢溂娉ず鐪惰�鍑吼煒傦級銆�/p>

.gitlab-ci.yml閰嶇疆锛�/p>

before_script:
  - echo "Restoring NuGet Packages..."
  - C:\NuGet\nuget.exe restore "src\CNBlogsCI-Sample.sln"

build鎴愬姛鏃ュ織锛�/p>

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Fetching changes...
HEAD is now at 1ac80d7 test commit
From https://gitlab.com/dev/CNBlogsCI-Sample
   1ac80d7..683a8bc  master     -> origin/master
Checking out 683a8bcb as master...
Previous HEAD position was 1ac80d7... test commit
HEAD is now at 683a8bc... test commit
$ echo "Restoring NuGet Packages..."
Restoring NuGet Packages...
$ C:\NuGet\nuget.exe restore "src\CNBlogsCI-Sample.sln"
Installing 'AutoMapper 4.2.1'.
Successfully installed 'AutoMapper 4.2.1'.

Build succeeded

鐪嬩技绠�崟鐨勭粨鏋滐紝浣嗚繃绋嬬湡鏄お鎵泲浜嗭紝濡傛灉鎴戝綋鏃剁湅鍒扮被浼艰繖绡囧崥鏂囧垎浜紝涔熶笉鑷充簬濡傛锛岃繕娌″畬锛岀户缁�銆傘�

3. build *.sln

杩欐浠诲姟锛氫娇鐢�CI锛�build 鐢熸垚瑙e喅鏂规涓殑椤圭洰銆�/p>

鐢熸垚瑙e喅鏂规鐨勯棶棰樿В鍐宠繃绋嬬浉瀵圭畝鍗曚簺锛屼笉杩囦笂闈㈡紡鎺変簡涓�锛岃繖杈瑰啀琛ュ厖涓嬶紝.gitlab-ci.yml閰嶇疆锛�/p>

stages:
  - build

job:
  stage: build
  script:
  - echo "Release build..."
  - C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /consoleloggerparameters:ErrorsOnly /maxcpucount /nologo /property:Configuration=Release /verbosity:quiet "CNBlogsCI-Sample.sln"
  tags: 
  except:
  - tags

閿欒鏃ュ織锛�/p>

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Fetching changes...
HEAD is now at 07a6ffd Merge branch 'master' of gitlab.com:dev/CNBlogsCI-Sample
From https://gitlab.com/dev/CNBlogsCI-Sample
   07a6ffd..73bd820  master     -> origin/master
Checking out 73bd8207 as master...
Previous HEAD position was 07a6ffd... Merge branch 'master' of gitlab.com:dev/CNBlogsCI-Sample
HEAD is now at 73bd820... test commit
$ echo "Release build..."
Release build...
$ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /consoleloggerparameters:ErrorsOnly /maxcpucount /nologo /property:Configuration=Release /verbosity:quiet "CNBlogsCI-Sample.sln"
MSBUILD : error MSB1009: 锟斤拷目锟侥硷拷锟斤拷锟斤拷锟节★拷
锟斤拷锟斤拷: CNBlogsCI-Sample.sln

ERROR: Build failed: exit status 1

杩欎釜閿欒鍜屾渶寮�鐨勪贡鐮侀敊璇竴鏍凤紝鏈煡鐨勯敊璇紝鏃犱粠涓嬫墜锛屽悗鏉ワ紝鍙堟棤鎰忛棿鎼滃埌浜嗕竴涓�Gitlab Issue锛堝ソ澶氭棤鎰忛棿馃槃锛屾病鍔炴硶锛孏oogle 鍙兘鎼滅储鎵�湁鍙兘鐨勫叧閿瓧锛夛細Question about local project path

.gitlab-ci.yml閰嶇疆鏀逛负锛�/p>

stages:
  - build

job:
  stage: build
  script:
  - ls
  - echo "Release build..."
  - C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /consoleloggerparameters:ErrorsOnly /maxcpucount /nologo /property:Configuration=Release /verbosity:quiet "CNBlogsCI-Sample.sln"
  tags: 
  except:
  - tags

鐒跺悗鐪嬪埌浜嗚缁嗛敊璇紙鍙堟湁鎴忎簡馃槒锛夛細

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Fetching changes...
HEAD is now at eb2ec26 Update .gitlab-ci.yml
Checking out eb2ec265 as master...
HEAD is now at eb2ec26... Update .gitlab-ci.yml
$ ls


    Directory: C:\Multi-Runner\builds\5ae63365\0\dev\CNBlogsCI-Sample


Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
d-----         5/4/2016  10:26 AM                src                                                                   
-a----         5/4/2016  11:19 AM            315 .gitlab-ci.yml                                                        
$ echo "Release build..."
Release build...
$ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /consoleloggerparameters:ErrorsOnly /maxcpucount /nologo /property:Configuration=Release /verbosity:quiet "CNBlogsCI-Sample.sln"
MSBUILD : error MSB1009: Project file does not exist.
Switch: CNBlogsCI-Sample.sln



ERROR: Build failed: exit status 1

error MSB1009: Project file does not exist.杩欎釜閿欒灏卞緢娓呮櫚浜嗭紝椤圭洰鏂囦欢鎵句笉鍒帮紝涔熷氨鏄病鏈夋壘鍒�code>CNBlogsCI-Sample.sln锛屾�涔堜細鍛紵閲嶆柊鏌ョ湅浜�Gitlab 涓殑椤圭洰鏂囦欢鐩綍锛�code>CNBlogsCI-Sample.sln鍦ㄦ牴鐩綍涓嬬殑src鐩綍涓嬶紝閲嶆柊淇敼涓�code>.gitlab-ci.yml閰嶇疆锛�/p>

stages:
  - build

job:
  stage: build
  script:
  - ls
  - echo "Release build..."
  - C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /consoleloggerparameters:ErrorsOnly /maxcpucount /nologo /property:Configuration=Release /verbosity:quiet "src/CNBlogsCI-Sample.sln"
  tags: 
  except:
  - tags

build鎴愬姛锛屾棩蹇楄鎯咃細

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Fetching changes...
HEAD is now at a51aeea test commit
From https://gitlab.com/dev/CNBlogsCI-Sample
   a51aeea..170fbc4  master     -> origin/master
Checking out 170fbc4a as master...
Previous HEAD position was a51aeea... test commit
HEAD is now at 170fbc4... test commit
$ ls


    Directory: C:\Multi-Runner\builds\5ae63365\0\dev\CNBlogsCI-Sample


Mode                LastWriteTime         Length Name                                                                  
----                -------------         ------ ----                                                                  
d-----         5/4/2016  11:38 AM                src                                                                   
-a----         5/4/2016  11:38 AM            319 .gitlab-ci.yml                                                        
$ echo "Release build..."
Release build...
$ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /consoleloggerparameters:ErrorsOnly /maxcpucount /nologo /property:Configuration=Release /verbosity:quiet "src/CNBlogsCI-Sample.sln"



Build succeeded

4. run unit tests

杩欐浠诲姟锛氫娇鐢�CI锛�run 璺戣В鍐虫柟妗堜腑鐨勫崟鍏冩祴璇曪紝鍙互鎴愪负鑷姩鍖栨祴璇曘�

杩欐鍩烘湰涓婃病鏈変粈涔堥棶棰樿В鍐宠繃绋嬶紝鍥犱负 Google 瀹屽叏鎼滀笉鍒扮浉鍏宠祫鏂欙紝鎵�互锛屾垜鏈�悗鏄寜鐓ф垜鐨勬兂娉曞疄鐜扮殑锛寈Unit 闄や簡鐢�VS2015 杩涜璺戝崟鍏冩祴璇曞锛屾垜浠繕鍙互鐢ㄥ懡浠よ鐨勬柟寮忥紝鎵撳紑 cmd 杈撳叆锛�code>C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary2\bin\debug\ClassLibrary2.dll"锛岀粨鏋滃涓嬶細

C:\Users\xishuai\Desktop\CNBlogs\CNBlogsCI-Sample\src> C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary2\bin\debug\ClassLibrary2.dll"
xUnit.net Console Runner (64-bit .NET 4.0.30319.42000)
  Discovering: ClassLibrary2
  Discovered:  ClassLibrary2
  Starting:    ClassLibrary2
    ClassLibrary2.Class1.Test2 [FAIL]
      Assert.True() Failure
      Expected: True
      Actual:   False
      Stack Trace:
        ClassLibrary2\Class1.cs(21,0): at ClassLibrary2.Class1.Test2()
  Finished:    ClassLibrary2
=== TEST EXECUTION SUMMARY ===
   ClassLibrary2  Total: 2, Errors: 0, Failed: 1, Skipped: 0, Time: 0.224s

濂斤紝鏃㈢劧鍛戒护琛屽彲浠ヨ窇鍗曞厓娴嬭瘯锛岄偅涔堟垜浠氨鍙互鍦�code>.gitlab-ci.yml涓坊鍔犺剼鏈厤缃紝濡備笅锛�/p>

stages:
  - build
  - test

before_script:
  - echo "Restoring NuGet Packages..."
  - C:\NuGet\nuget.exe restore "src\CNBlogsCI-Sample.sln"

build_job:
  stage: build
  script:
  - echo "Release build..."
  - C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /consoleloggerparameters:ErrorsOnly /maxcpucount /nologo /property:Configuration=Release /verbosity:quiet "src\CNBlogsCI-Sample.sln"
  except:
  - tags

test_job:
  stage: test
  script:
  - echo "Tests run..."
  - C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary2\bin\debug\ClassLibrary2.dll"
  - C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary3\bin\debug\ClassLibrary3.dll"

xUnit 鍗曞厓娴嬭瘯涓嶉�杩囨棩蹇楋細

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Fetching changes...
Removing src/ClassLibrary1/bin/
Removing src/ClassLibrary1/obj/
Removing src/ClassLibrary2/bin/Release/
Removing src/ClassLibrary2/obj/
Removing src/ClassLibrary3/bin/
Removing src/ClassLibrary3/obj/
Removing src/packages/
HEAD is now at d176025 test commit
Checking out d1760259 as master...
HEAD is now at d176025... test commit
$ echo "Restoring NuGet Packages..."
Restoring NuGet Packages...
$ C:\NuGet\nuget.exe restore "src\CNBlogsCI-Sample.sln"
Installing 'xunit.abstractions 2.0.0'.
Installing 'xunit.assert 2.1.0'.
Installing 'xunit 2.1.0'.
Installing 'AutoMapper 4.2.1'.
Successfully installed 'xunit 2.1.0'.
Installing 'xunit.core 2.1.0'.
Successfully installed 'xunit.abstractions 2.0.0'.
Successfully installed 'xunit.core 2.1.0'.
Installing 'xunit.extensibility.core 2.1.0'.
Successfully installed 'xunit.assert 2.1.0'.
Installing 'xunit.extensibility.execution 2.1.0'.
Installing 'xunit.runner.console 2.1.0'.
Successfully installed 'AutoMapper 4.2.1'.
Successfully installed 'xunit.runner.console 2.1.0'.
Successfully installed 'xunit.extensibility.core 2.1.0'.
Successfully installed 'xunit.extensibility.execution 2.1.0'.
$ echo "Tests run..."
Tests run...
$ C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary2\bin\debug\ClassLibrary2.dll"
xUnit.net Console Runner (64-bit .NET 4.0.30319.42000)
  Discovering: ClassLibrary2
  Discovered:  ClassLibrary2
  Starting:    ClassLibrary2
  Finished:    ClassLibrary2
=== TEST EXECUTION SUMMARY ===
   ClassLibrary2  Total: 2, Errors: 0, Failed: 0, Skipped: 0, Time: 0.179s
$ C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary3\bin\debug\ClassLibrary3.dll"
error: file not found: src\ClassLibrary3\bin\debug\ClassLibrary3.dll

ERROR: Build failed: exit status 1

xUnit 鍗曞厓娴嬭瘯閫氳繃鏃ュ織锛�/p>

gitlab-ci-multi-runner 1.1.3 (a470667)
Using Shell executor...
Running on DESKTOP-2P9GHDD...
Fetching changes...
Removing src/ClassLibrary1/bin/
Removing src/ClassLibrary1/obj/
Removing src/ClassLibrary2/bin/Release/
Removing src/ClassLibrary2/obj/
Removing src/ClassLibrary3/bin/Release/
Removing src/ClassLibrary3/obj/
Removing src/packages/
HEAD is now at 2467772 test commit
Checking out 2467772f as master...
HEAD is now at 2467772... test commit
$ echo "Restoring NuGet Packages..."
Restoring NuGet Packages...
$ C:\NuGet\nuget.exe restore "src\CNBlogsCI-Sample.sln"
Installing 'AutoMapper 4.2.1'.
Installing 'xunit.abstractions 2.0.0'.
Installing 'xunit.assert 2.1.0'.
Installing 'xunit 2.1.0'.
Successfully installed 'xunit 2.1.0'.
Installing 'xunit.core 2.1.0'.
Successfully installed 'xunit.abstractions 2.0.0'.
Successfully installed 'xunit.core 2.1.0'.
Installing 'xunit.extensibility.execution 2.1.0'.
Installing 'xunit.extensibility.core 2.1.0'.
Successfully installed 'xunit.assert 2.1.0'.
Installing 'xunit.runner.console 2.1.0'.
Successfully installed 'AutoMapper 4.2.1'.
Successfully installed 'xunit.runner.console 2.1.0'.
Successfully installed 'xunit.extensibility.core 2.1.0'.
Successfully installed 'xunit.extensibility.execution 2.1.0'.
$ echo "Tests run..."
Tests run...
$ C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary2\bin\debug\ClassLibrary2.dll"
xUnit.net Console Runner (64-bit .NET 4.0.30319.42000)
  Discovering: ClassLibrary2
  Discovered:  ClassLibrary2
  Starting:    ClassLibrary2
  Finished:    ClassLibrary2
=== TEST EXECUTION SUMMARY ===
   ClassLibrary2  Total: 2, Errors: 0, Failed: 0, Skipped: 0, Time: 0.194s
$ C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary3\bin\debug\ClassLibrary3.dll"
xUnit.net Console Runner (64-bit .NET 4.0.30319.42000)
  Discovering: ClassLibrary3
  Discovered:  ClassLibrary3
  Starting:    ClassLibrary3
  Finished:    ClassLibrary3
=== TEST EXECUTION SUMMARY ===
   ClassLibrary3  Total: 1, Errors: 0, Failed: 0, Skipped: 0, Time: 0.184s

Build succeeded

鍩烘湰涓婂疄鐜颁簡鎴戜滑鎯宠鐨勬晥鏋滐紝浣嗚繖绉嶅疄鐜版柟寮忔湁涓や釜涓嶅ソ鐨勫湴鏂癸細

  • 闇�灏嗗崟鍏冩祴璇曠殑 *.dll 鏂囦欢涓婁紶鍒�git 璧勬簮搴撱�
  • 姣忓鍔犱竴涓崟鍏冩祴璇曢」鐩紝灏卞繀椤诲湪.gitlab-ci.yml涓坊鍔犱竴娈佃剼鏈�

鎴戜釜浜鸿寰�CI 涓殑鑷姩鍖栨祴璇曪紝鑲畾涓嶆槸鍍忔垜杩欐牱鎼炵殑锛屼絾瀹炲湪鎵句笉鍒扮浉鍏宠祫鏂欙紝濡傛灉澶у鐭ユ倝锛岃繕璇峰憡鐭ワ紝鎰熻阿锝�/p>

鍙﹀锛屽鏋滄槸 ASP.NET 5 椤圭洰锛岃繘琛岃嚜鍔ㄥ寲娴嬭瘯閰嶇疆锛屼細闈炲父绠�崟锛岄厤缃涓嬶細

test:
  stage: test
  script:
  - echo "Tests run..."
  - dnx test #鎴栬� dotnet test

5. configue .gitlab-ci.yml

.gitlab-ci.yml瀹樻柟璧勬枡锛�a href="http://doc.gitlab.com/ee/ci/yaml/README.html" class="uri">http://doc.gitlab.com/ee/ci/yaml/README.html

鍏朵粬绀轰緥锛�/p>

  • http://stackoverflow.com/questions/32964953/gitlab-ci-and-msbuild-with-tests
  • https://github.com/CWISoftware/accounts/blob/master/.gitlab-ci.yml
  • http://www.timtilberg.com/tag/gitlab/
  • http://doc.gitlab.com/ee/ci/yaml/README.html#stages
  • https://github.com/travis-ci/travis-ci/issues/5210

.gitlab-ci.yml涓殑閰嶇疆璇存槑锛屼笂闈㈢殑瀹樻柟璧勬枡浠嬬粛鐨勯潪甯歌缁嗭紝涓嬮潰鎴戝啀绠�崟浠嬬粛涓嬶紝灏辩敤鎴戣繖娆¢儴缃�CI 瀹屽杽鍚庣殑.gitlab-ci.yml閰嶇疆锛�/p>

stages:
  - build
  - test

before_script:
  - echo "Restoring NuGet Packages..."
  - C:\NuGet\nuget.exe restore "src\CNBlogsCI-Sample.sln"
  only:
  - master

build_job:
  stage: build
  script:
  - echo "Release build..."
  - C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe /consoleloggerparameters:ErrorsOnly /maxcpucount /nologo /property:Configuration=Release /verbosity:quiet "src\CNBlogsCI-Sample.sln"
  except:
  - tags
  only:
  - master

test_job:
  stage: test
  script:
  - echo "Tests run..."
  - C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary2\bin\debug\ClassLibrary2.dll"
  - C:\xunit.runner.console\tools\xunit.console.exe "src\ClassLibrary3\bin\debug\ClassLibrary3.dll"
  only:
  - master

stage缈昏瘧涓�strong>闃舵鐨勬剰鎬濓紝鍦�strong>鏋勫缓鐨勮繃绋嬩腑锛屽繀椤昏鏈変竴涓厛鍚庨『搴忥紝鏈�笂闈㈢殑stages閰嶇疆鎰忔�鏄紝鍏堟瀯寤洪樁娈典负build鐨�code>job锛岀劧鍚庡啀鏋勫缓闃舵涓�code>test鐨�code>job锛屼笅闈�code>build_job鍜�code>test_job閮芥槸job锛屽鏋滀笉閰嶇疆stages锛岄粯璁や负锛�/p>

stages:
  - build
  - test
  - deploy

before_script鐨勬剰鎬濇槸锛屾墽琛屽湪鎵�湁鐨�code>job涔嬪墠鐨勮剼鏈紝姣斿鏋勫缓build_job鍜�code>test_job閮藉厛鎵цbefore_script锛�code>build_job鍜�code>test_job涓殑stage閰嶇疆锛屾剰鎬濇槸姝�code>job灞炰簬鍝釜stage锛岃繖涓�code>stage灏辨槸鏈�笂闈㈢殑stages閰嶇疆锛岄櫎浜嗛粯璁ょ殑build,test鍜�code>deploy锛屼綘涔熷彲浠ユ坊鍔犺嚜瀹氫箟鐨�code>stage锛屽彟澶栵紝濡傛灉job涓嶆坊鍔�code>stage閰嶇疆锛岄粯璁ら厤缃负test锛屾瘮濡備笂闈㈢殑test_job锛屽氨鍙互鐪佺暐stage: test閰嶇疆銆�/p>

鍙﹀锛�code>job杩樻湁涓�釜when: on_failure/on_success /always閰嶇疆锛屽鏋滄垜浠job杩涜浜�code>stage閰嶇疆锛岄粯璁ら兘浼氭槸when: on_success锛�/p>

鍔堣崋鏂╂锛欸itlab 閮ㄧ讲 CI 鎸佺画闆嗘垚_第3张图片

only - master鐨勬剰鎬濇槸锛屽彧鏈塦master鍒嗘敮鎵嶄細杩涜鏋勫缓锛�code>script鐨勬剰鎬濆緢鏄庝簡锛屽氨鏄鎵ц鐨勮剼鏈懡鍚嶃�

6. configue build status badge image

鏋勫缓鐘舵�寰界珷锛屽氨鏄垜浠钩甯稿湪 Github 椤圭洰涓湅鍒版瀯寤哄浘鏍囷紝鏈�code>pass鍜�code>failing绛夌瓑銆�/p>

Gitlab CI 涓殑鏁欑▼ builds-badge 鐪熺殑寰堝潙鐖癸紝鎬庝箞璇曢兘涓嶈锛屽悗鏉ユ棤鎰忛棿鐪嬪埌 Gitlab 椤圭洰鐨勪竴涓�椤�Settings > Badges锛�/p>

澶嶅埗涓婇潰鐨勪唬鐮侊紝鐒跺悗娣诲姞鍦�code>README.md鏂囦欢涓細

[![build status](https://gitlab.com/dev/CNBlogsCI-Sample/badges/master/build.svg)](https://gitlab.com/dev/CNBlogsCI-Sample/commits/master)

杩欐牱鍦�code>commit``bulid鐨勬椂鍊欙紝灏变細鍔ㄦ�鐨勬樉绀�code>bulid鐨勮繃绋嬪拰缁撴灉锛屽苟涓旀槸鍥剧墖鏄剧ず銆�/p>

鍔堣崋鏂╂锛欸itlab 閮ㄧ讲 CI 鎸佺画闆嗘垚_第4张图片

Gitlab 閮ㄧ讲濂�CI 涔嬪悗锛屾垜浠細鍙戠幇锛屽湪椤圭洰涓殢澶勫彲瑙佽繖鏍风殑鍥炬爣锛�/p>

鍔堣崋鏂╂锛欸itlab 閮ㄧ讲 CI 鎸佺画闆嗘垚_第5张图片

杩欑瘒鍗氭枃娌℃湁浠�箞闃呰浠峰�锛屽洜涓洪兘鏄浂闆剁纰庣殑闂鍜岃В鍐崇邯褰曪紝娌℃湁浠�箞鍙鎬э紝濡傛灉浣犺兘闃呰鍒拌繖锛屾垜鐪熺殑浼氬緢鎰熷姩銆�/p>

鍒嗕韩鏄湁浠峰�鐨勪竴浠朵簨锛屽鏋滃洯鍙嬪湪閬囧埌鐩稿悓闂鐨勬椂鍊欙紝鍙互 Google 鍒拌繖绡囧崥鏂囷紝閭e啓杩欑瘒鍗氭枃涔熷氨鍊间簡馃槒銆�/p>

你可能感兴趣的:(鍔堣崋鏂╂锛欸itlab 閮ㄧ讲 CI 鎸佺画闆嗘垚)