久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營(yíng)的一線實(shí)戰(zhàn)洞察。

Python項(xiàng)目CI/CD流水線實(shí)戰(zhàn):從依賴管理到自動(dòng)化發(fā)布

Python項(xiàng)目CI/CD流水線實(shí)戰(zhàn):從依賴管理到自動(dòng)化發(fā)布 很多Python項(xiàng)目團(tuán)隊(duì)有個(gè)通病代碼寫完本地一跑就完事測(cè)試敲一遍就推了等合并到主分支、上線出故障才開始手忙腳亂。我在過去的實(shí)戰(zhàn)里給不同類型Python項(xiàng)目——從依賴復(fù)雜的算法服務(wù)到快速迭代的Web后端——都配過一套持續(xù)集成/持續(xù)部署CI/CD流水線今天把沉淀的思路、工具選擇和實(shí)操細(xì)節(jié)完整攤開說一遍。這篇內(nèi)容適合剛接觸CI/CD的初級(jí)開發(fā)者也適合已經(jīng)跑了Jenkins或GitHub Actions但總被緩存和依賴問題折磨的團(tuán)隊(duì)哪怕你現(xiàn)在還沒準(zhǔn)備好上完整的持續(xù)部署只要能先把“提交代碼后自動(dòng)跑測(cè)試和檢查”這一件事做好這篇文章就能給你省下大量時(shí)間。我一直覺得CI/CD對(duì)于Python項(xiàng)目有一種獨(dú)特的厚重感。Java和Go有成熟的構(gòu)建工具編譯自己會(huì)兜底錯(cuò)誤但Python是動(dòng)態(tài)語言環(huán)境的差異、依賴的版本、解釋器的行為每一個(gè)環(huán)節(jié)都可能讓“我電腦上明明能跑”變成一句讓人頭疼的話。所以我的思路從來不是“把CI/CD當(dāng)成上線按鈕”而是把它當(dāng)成一套完整的“代碼體檢和心理護(hù)欄”下面從設(shè)計(jì)拆解開始說起。1. 整體設(shè)計(jì)與思路拆解1.1 先搞懂CI/CD是在解決什么痛點(diǎn)持續(xù)集成Continuous Integration的核心含義是讓團(tuán)隊(duì)所有成員的代碼頻繁合并到一個(gè)主干上并在合并之后第一時(shí)間通過自動(dòng)化腳本驗(yàn)證這套代碼是否還能正常運(yùn)行。持續(xù)部署/持續(xù)交付Continuous Delivery/Deployment則進(jìn)一步把通過驗(yàn)證的產(chǎn)物自動(dòng)推到測(cè)試環(huán)境甚至生產(chǎn)環(huán)境。用生活類比來說CI就像是每天下班前的例行體檢CD則是體檢合格后直接給你開好第二天的通行證。但我看到太多團(tuán)隊(duì)把CI/CD做成了“自我感動(dòng)”。流水線里跑了一堆步驟真實(shí)能攔截的問題卻沒幾個(gè)最后大家只想快速跳過紅叉。問題通常出在設(shè)計(jì)上把CI/CD當(dāng)成一個(gè)靈丹妙藥而不是當(dāng)成一個(gè)需要結(jié)合自己項(xiàng)目特性去量身定做的流程。我的建議是先想清楚三個(gè)問題再動(dòng)手你的項(xiàng)目有哪些“必須在合并前明確的紅線”你的依賴和運(yùn)行環(huán)境有多少種組合需要同時(shí)驗(yàn)證你的發(fā)布流程是人工審批多還是全自動(dòng)多1.2 Python項(xiàng)目做CI/CD的三個(gè)特殊難點(diǎn)第一個(gè)難點(diǎn)是環(huán)境隔離。Python的依賴真的很容易變成依賴地獄系統(tǒng)自帶Python、虛擬環(huán)境、Docker和不同包管理器之間的版本糾纏足以把一個(gè)簡(jiǎn)單的測(cè)試跑得稀碎。第二個(gè)難點(diǎn)是構(gòu)建產(chǎn)物并不像編譯型語言那樣有清晰邊界Python打包成wheel和sdist之后還要做安裝驗(yàn)證否則很容易出現(xiàn)“構(gòu)建成功但裝不上”的情況。第三個(gè)難點(diǎn)是動(dòng)態(tài)類型的“表面繁榮”沒有編譯器的檢查只有靠靜態(tài)分析、類型標(biāo)注和測(cè)試覆蓋去守住質(zhì)量線。正是因?yàn)檫@三點(diǎn)我在設(shè)計(jì)流水線時(shí)從來不會(huì)把全部壓力放在某一個(gè)環(huán)節(jié)上。常規(guī)思路是分四層守護(hù)語法和風(fēng)格檢查負(fù)責(zé)基礎(chǔ)動(dòng)作類型檢查負(fù)責(zé)隱性問題單元測(cè)試加覆蓋度負(fù)責(zé)行為驗(yàn)證復(fù)雜度度和集成測(cè)試負(fù)責(zé)跨模塊可靠性。這四層會(huì)在每次提交時(shí)都跑一遍有任意一層失敗直接從源頭堵住代碼合并。1.3 一切設(shè)計(jì)圍繞“快速失敗”和“可重復(fù)執(zhí)行”我踩過最大的一次坑是一套跑完所有測(cè)試要半個(gè)小時(shí)的流水線。半小時(shí)看著不長(zhǎng)但一旦團(tuán)隊(duì)有幾十個(gè)分支同時(shí)活躍等待時(shí)間會(huì)拖垮所有人的開發(fā)節(jié)奏然后大家開始想辦法繞過CI整個(gè)流程就形同虛設(shè)。所以后來我給自己定了一條原則分支級(jí)流水線的核心目標(biāo)不是把所有事情都做完而是在5到10分鐘內(nèi)快速給出“能不能合”的信號(hào)更重的集成測(cè)試、發(fā)布流程和端到端驗(yàn)證交給合并到主干或者打好版本標(biāo)簽之后再觸發(fā)??芍貜?fù)執(zhí)行這一點(diǎn)也非常核心。如果一段流水線跑十次有九個(gè)結(jié)果那它就沒有參考價(jià)值。為了保證可重復(fù)性我通常會(huì)盯住三個(gè)東西依賴鎖定必須做到哈希級(jí)別不要裸跑pip install requirements.txt而不用約束文件Python解釋器指定明確版本和補(bǔ)丁版本不要只寫python-version: 3.12這樣的大版本號(hào)所有外網(wǎng)調(diào)用和數(shù)據(jù)源必須有明確的mock策略不能讓測(cè)試結(jié)果取決于網(wǎng)絡(luò)心情。1.4 拆解一套流水線的標(biāo)準(zhǔn)階段我習(xí)慣把Python項(xiàng)目的流水線分成六個(gè)標(biāo)準(zhǔn)階段準(zhǔn)備階段檢出代碼、安裝解釋器、緩存恢復(fù)、依賴階段安裝鎖定依賴并做完整性校驗(yàn)、檢查階段靜態(tài)分析、類型檢查、格式檢查、測(cè)試階段單元測(cè)試、覆蓋率、并行策略、構(gòu)建階段構(gòu)建wheel、sdist并做可安裝性驗(yàn)證、發(fā)布階段打標(biāo)簽、推送到制品庫(kù)或執(zhí)行部署腳本。每個(gè)階段之間盡量做成無狀態(tài)也就是上一個(gè)階段產(chǎn)生的緩存和產(chǎn)物要能明確傳給下一階段不留隱式的全局狀態(tài)。有人可能覺得這個(gè)劃分太“重”了一個(gè)小工具項(xiàng)目沒必要弄這么多。但我的實(shí)際經(jīng)驗(yàn)是階段的分層其實(shí)不增加多少配置成本卻能讓你在故障排查時(shí)瞬間定位到底卡在哪一環(huán)。后面第4部分里我會(huì)用一套GitHub Actions的完整例子把每個(gè)階段變成可跑的真實(shí)配置。2. 工具選型解析不要一上來就跟風(fēng)2.1 托管平臺(tái)CI的橫評(píng)與真實(shí)體驗(yàn)市面上主流的托管CI大概分成三波以GitHub Actions為代表的平臺(tái)內(nèi)嵌型以GitLab CI為代表的DevOps全流程型以Jenkins為代表的自托管老將型。另外CircleCI、Azure DevOps、Travis CI甚至部分團(tuán)隊(duì)自己寫一套基于飛書的流水線也都有一定的用戶基礎(chǔ)。我不打算寫一篇工具夸夸文只說我實(shí)際接觸下來最直觀的感受。GitHub Actions是目前Python生態(tài)里接入最順滑的選擇。項(xiàng)目就在GitHub上托管工作流文件直接藏在倉(cāng)庫(kù)的.github/workflows目錄里拉取請(qǐng)求和分支合并都能自動(dòng)觸發(fā)官方維護(hù)的actions/setup-python在解釋器安裝和緩存處理上確實(shí)省心。缺點(diǎn)是如果你所在團(tuán)隊(duì)的網(wǎng)絡(luò)環(huán)境訪問公共倉(cāng)庫(kù)不穩(wěn)定下載action和安裝包的體驗(yàn)會(huì)打折扣需要配置鏡像或者私有化部署。GitLab CI給我的感覺是配置結(jié)構(gòu)更統(tǒng)一。所有流水線定義在.gitlab-ci.yml里Runner可以運(yùn)行在Kubernetes集群上做動(dòng)態(tài)擴(kuò)容而且內(nèi)置了環(huán)境管理、部署審批和監(jiān)控面板適合那種一條龍需求很強(qiáng)的團(tuán)隊(duì)。缺點(diǎn)是中小型Python項(xiàng)目用起來偶爾會(huì)讓人覺得配置還挺復(fù)雜純碎為了跑測(cè)試而引入GitLab全家桶有點(diǎn)重。Jenkins適合什么場(chǎng)景呢適合那些已經(jīng)跑在自有機(jī)房、有合規(guī)要求、需要深度自定義插件的傳統(tǒng)團(tuán)隊(duì)。我見過不少老項(xiàng)目Jenkins里積攢了幾十甚至上百個(gè)插件看起來功能強(qiáng)大但一旦有人離職流水線就成了誰都不敢碰的黑盒子。我的建議是優(yōu)先選擇托管平臺(tái)的集成支持只有真有過硬的自部署需求再考慮Jenkins。附一個(gè)簡(jiǎn)單的對(duì)比表工具托管方式配置產(chǎn)物適合場(chǎng)景主要成本GitHub Actions云托管workflow YAMLGitHub倉(cāng)庫(kù)項(xiàng)目快速上手分鐘數(shù)計(jì)費(fèi)需要網(wǎng)絡(luò)暢通GitLab CI云/自托管.gitlab-ci.yml需要一站式DevOps閉環(huán)配置復(fù)雜度較高Jenkins自托管Jenkinsfile大規(guī)模自運(yùn)維體系維護(hù)成本高插件歷史債本地腳本 act本地運(yùn)行本地命令還不準(zhǔn)備引入平臺(tái)CI時(shí)過度功能邊界有限2.2 本地輔助工具pre-commit、tox和poetry真正讓我愛上這套流程的其實(shí)是本地端的輔助工具。pre-commit幫你在提交之前就攔掉明顯的低級(jí)問題相當(dāng)于在CI前面加了一道道閘tox能讓你在本地一鍵模擬多種Python版本和依賴組合的測(cè)試環(huán)境在代碼還沒推到遠(yuǎn)端之前就把兼容性問題暴露出來poetry或者pdm則承擔(dān)依賴解析和鎖定的職能。關(guān)于pre-commit有一個(gè)常見的誤解以為它只是做統(tǒng)一代碼風(fēng)格。其實(shí)它的能力邊界遠(yuǎn)不止于此修復(fù)混用制表符和空格、檢查調(diào)試代碼殘留、校驗(yàn)配置文件格式、掃描敏感信息、在GitHub Actions里看到我無意間提交的密鑰文件時(shí)救了我好幾次。它通過鉤子機(jī)制綁定到git的commit階段如果某個(gè)檢查點(diǎn)失敗git提交會(huì)被直接攔下。tox這類工具更專業(yè)一點(diǎn)它會(huì)為每個(gè)目標(biāo)環(huán)境創(chuàng)建獨(dú)立的虛擬環(huán)境執(zhí)行你在tox.ini里定義好的測(cè)試命令。你只要在本地跑一遍tox就等于是把CI里的關(guān)鍵測(cè)試動(dòng)作提前模擬了一次。把CI的一部分流程下放到本地聽著有點(diǎn)“脫褲子放屁”但實(shí)際上能極大縮短反饋鏈路因?yàn)楸镜丨h(huán)境錯(cuò)誤提示比CI日志更直觀。2.3 工具選型的三條經(jīng)驗(yàn)第一條經(jīng)驗(yàn)是從最小可用開始。任何工具能先用一條最簡(jiǎn)單的流水線跑通測(cè)試就不要第一天就追求多階段多環(huán)境的大而全。第二條經(jīng)驗(yàn)是工具必須可被代碼化。如果團(tuán)隊(duì)的CI配置只能通過網(wǎng)頁界面點(diǎn)點(diǎn)點(diǎn)去改那一定走不遠(yuǎn)一定要把定義文件放在倉(cāng)庫(kù)里用版本管理去追變更。第三條經(jīng)驗(yàn)是計(jì)算資源要能彈性伸縮。托管平臺(tái)的容器化機(jī)制天然適合Python項(xiàng)目這種用完即走的模式比維護(hù)一臺(tái)永遠(yuǎn)在跑的Jenkins節(jié)點(diǎn)要省心得多。3. 核心細(xì)節(jié)剖析與實(shí)操要點(diǎn)3.1 依賴管理從requirements鎖定到鎖定文件Python依賴管理是CI/CD里最陰險(xiǎn)的坑。你本地昨天裝好的包版本和今天CI里解析出來的包版本可能就不一樣然后就會(huì)出現(xiàn)那種最無語的“我這邊能過為什么CI掛了”事件。我的標(biāo)準(zhǔn)做法是使用約束文件requirements.in里只寫頂層依賴再用pip-tools或者poetry生成一份完全鎖定的requirements.txt其中每個(gè)包都帶上固定版本號(hào)如果條件允許盡量還帶上對(duì)應(yīng)的哈希值用來校驗(yàn)完整性。對(duì)于使用poetry的項(xiàng)目我會(huì)確保提交poetry.lock文件并建議在CI里使用poetry install --no-root --no-interaction。注意--no-root這個(gè)細(xì)節(jié)它在依賴不完整或者根項(xiàng)目有問題時(shí)會(huì)跳過安裝項(xiàng)目本身的流程更貼合CI里去“驗(yàn)證依賴是否能安裝”的目標(biāo)。哪怕是玩票性質(zhì)的小項(xiàng)目只要切到CI環(huán)境中我都不建議直接裸跑pip install -r requirements.txt因?yàn)槟銦o法保證今天裝上來的包和昨天是一致的。另外我見過不少團(tuán)隊(duì)在流水線里執(zhí)行版本升級(jí)pip install --upgrade -r requirements.txt這是一個(gè)很隱蔽的坑。這個(gè)命令會(huì)將鎖定的版本全部升級(jí)CI結(jié)果和開發(fā)手里的結(jié)果完全脫節(jié)。正確姿勢(shì)是如果確實(shí)需要升級(jí)先在開發(fā)環(huán)境里用依賴解析工具更新鎖定文件再把這個(gè)文件提交到倉(cāng)庫(kù)之后由CI去做干凈的全新安裝。3.2 緩存策略怎么不出錯(cuò)怎么避坑緩存是CI/CD性能的關(guān)鍵但緩存錯(cuò)誤配置引發(fā)的干擾故障也最多。Python的依賴緩存目前主要圍繞兩個(gè)層面一是pip本身的下載緩存二是整個(gè)虛擬環(huán)境目錄。GitHub Actions里可以使用自帶的actions/setup-python配置cache: pip它會(huì)在執(zhí)行期間自動(dòng)處理pip緩存目錄按鍵生成緩存并自動(dòng)恢復(fù)。GitLab CI則可以用cache關(guān)鍵字配合key規(guī)則將requirements.txt的哈希值作為識(shí)別標(biāo)識(shí)。這里有一個(gè)非常關(guān)鍵的經(jīng)驗(yàn)如果鎖定文件沒有變化就不要強(qiáng)行重新安裝全部依賴。通過緩存恢復(fù)之后通??梢灾苯訌?fù)用虛擬環(huán)境然后僅增量執(zhí)行必要的安裝步驟。但如果某個(gè)依賴涉及系統(tǒng)動(dòng)態(tài)庫(kù)比如基于PyTorch或者某些編譯型擴(kuò)展單純緩存Python虛擬環(huán)境偶爾會(huì)遇到底層庫(kù)文件不匹配的情況。這種時(shí)候?qū)幙删彺鎝ip下載源也不要緩存venv把安裝這一步每次老老實(shí)實(shí)跑一遍往往比折騰半天找莫名報(bào)錯(cuò)要快。緩存失效時(shí)間也是一個(gè)值得關(guān)注的設(shè)置。GitHub Actions里緩存最長(zhǎng)可以保留數(shù)天但如果你的項(xiàng)目頻繁更新依賴一份過期緩存反而會(huì)拖慢任務(wù)。我把策略定為常規(guī)更新不作為破壞性變更只有依賴哈希發(fā)生變更時(shí)才強(qiáng)制刷新緩存但如果發(fā)現(xiàn)CI任務(wù)因?yàn)榫彺驽e(cuò)誤導(dǎo)致異常要果斷刪除緩存重新完整安裝。手動(dòng)加一個(gè)緩存清理工作流或者直接清緩存面板都是論壇里常用的應(yīng)急手段。3.3 測(cè)試與覆蓋率的正確姿勢(shì)測(cè)試是CI的核心但跑測(cè)試的方式很能體現(xiàn)細(xì)節(jié)差異。我的基礎(chǔ)配置是用pytest加pytest-xdist實(shí)現(xiàn)并行測(cè)試數(shù)量少的時(shí)候直接一把梭測(cè)試較龐大時(shí)按CPU核心數(shù)或者按目錄拆分調(diào)度器。值得注意的是pytest-xdist不保證測(cè)試函數(shù)行的執(zhí)行順序所以一旦項(xiàng)目里的測(cè)試有全局狀態(tài)相互依賴并行時(shí)很容易出現(xiàn)隨機(jī)失敗。解決方案分兩步離不開的全局狀態(tài)必須用fixture正確隔離然后把不適合并行的集成測(cè)試單獨(dú)放到另一個(gè)目錄或者用標(biāo)記排除。比如在pyproject.toml里這樣配置[tool.pytest.ini_options] testpaths [tests] addopts -n auto --dist loadgroup markers [integration: 集成測(cè)試不參與默認(rèn)并行]覆蓋率這塊我建議你不要過度追求100%。90%以上的覆蓋率如果只是靠mock刷上去那它對(duì)質(zhì)量的保護(hù)作用其實(shí)是虛假的。我更關(guān)注兩個(gè)指標(biāo)新增代碼是否有對(duì)應(yīng)的測(cè)試覆蓋被修改的核心模塊是否有覆蓋。CI里設(shè)置一個(gè)最低閾值比如整體低于80%直接失敗新增文件必須達(dá)到90%防止團(tuán)隊(duì)在提交代碼時(shí)“裸奔”。同時(shí)需要避免一個(gè)常見的坑就是發(fā)現(xiàn)覆蓋率報(bào)告里出現(xiàn)很多不需要關(guān)心的解釋器分支。這通常是因?yàn)闇y(cè)試的進(jìn)程繼承了一些環(huán)境變量而導(dǎo)致的意外路徑需要你在收集覆蓋率時(shí)指定好source參數(shù)只統(tǒng)計(jì)自己項(xiàng)目的代碼目錄不要去統(tǒng)計(jì)第三方庫(kù)和測(cè)試樁文件。3.4 靜態(tài)分析、類型檢查和格式門禁Python代碼在動(dòng)態(tài)語義上太過自由所以靜態(tài)工具就成了我的“人工代碼審查助手”?,F(xiàn)階段我主力推薦ruff來替代flake8、isort和pyupgrade因?yàn)樗俣瓤斓綆缀醺杏X不到存在配置統(tǒng)一在pyproject.toml里避免了一堆分散的配置文件。格式方面用black或者ruff format都可以選擇團(tuán)隊(duì)能接受的一種并嚴(yán)格執(zhí)行。類型檢查我建議用mypy設(shè)置嚴(yán)格模式后在每次提交時(shí)作為質(zhì)量門禁的一部分。很多人覺得mypy煩人因?yàn)樗鼤?huì)不停對(duì)第三方庫(kù)報(bào)錯(cuò)產(chǎn)生大量無效錯(cuò)誤。我的解法是顯式配置第三方庫(kù)的類型情況并且在接口邊界處多使用# type: ignore[code]而不是裸的# type: ignore這樣以后回顧時(shí)還能明白當(dāng)時(shí)為什么忽略而不是留下一堆“玄學(xué)標(biāo)記”。這些工具最好是配合pre-commit在本地先跑一遍CI再去跑一遍作為強(qiáng)約束。兩者的區(qū)別在于本地的pre-commit具有教促作用發(fā)現(xiàn)問題時(shí)你可以及時(shí)修復(fù)CI的嚴(yán)格檢查負(fù)責(zé)最后一道裁判責(zé)任不通過就不合并。配置pre-commit時(shí)我強(qiáng)烈建議把hook的pass_filenames屬性搞清楚有些鉤子適合單文件處理有些更適合全局執(zhí)行弄錯(cuò)了會(huì)出現(xiàn)本地通過但CI檢查失敗后又一個(gè)來回。3.5 構(gòu)建與打包不只是python -m build很多人以為構(gòu)建和打包就是把源代碼用wheel壓一遍。這個(gè)環(huán)節(jié)最容易出現(xiàn)的問題是你在CI里構(gòu)建成功了但在一臺(tái)干凈機(jī)器上安裝后運(yùn)行時(shí)卻缺少某些數(shù)據(jù)文件或資源目錄。這是因?yàn)镻ython包默認(rèn)只打包腳本和包內(nèi)文件靜態(tài)資源、版本號(hào)信息、入口點(diǎn)聲明都需要在打包配置中顯式寫明。我會(huì)在流水線的構(gòu)建階段做三件事第一件是用python -m build生成sdist和wheel第二件事是新建一個(gè)干凈的虛擬環(huán)境安裝生成的wheel文件并嘗試運(yùn)行一個(gè)最基本的命令入口第三件事是檢查wheel包里的文件清單確定沒有丟失資源文件。這三件事全通過才認(rèn)為構(gòu)建產(chǎn)物是可信的。關(guān)于構(gòu)建工具新項(xiàng)目我推薦用hatchling或者flit配置非常簡(jiǎn)潔如果是老項(xiàng)目還在用setuptools也還可以先用著但盡量在遷移時(shí)順手升級(jí)一次。重點(diǎn)是所有元數(shù)據(jù)不要重復(fù)手動(dòng)維護(hù)我的習(xí)慣是把版本號(hào)放在一個(gè)單一來源中通過importlib.metadata或者構(gòu)建工具動(dòng)態(tài)讀取Git標(biāo)簽避免__version__、pyproject.toml和README三處不一致的情況。3.6 發(fā)布與部署部署前必做的三件套發(fā)布階段是持續(xù)部署的臨門一腳。我的發(fā)布流水線里至少會(huì)包含三個(gè)動(dòng)作語義化版本檢查、發(fā)布說明生成和制品推送。語義化版本靠Git標(biāo)簽管理每次都從最新的tag遞增patch、minor還是major應(yīng)該有清晰規(guī)則不能“亂打”和“亂發(fā)”。發(fā)布說明可以從Git提交記錄中自動(dòng)提取但人工潤(rùn)色仍然是必要的用戶看到的是有價(jià)值的內(nèi)容而不是一堆雜亂提交消息。推送制品時(shí)私有倉(cāng)庫(kù)和公共PyPI的憑證都建議放在CI平臺(tái)的secret管理里不要直接寫死在工作流文件中。GitHub Actions天然有secrets機(jī)制GitLab CI也有protected variable合理使用這些能力能把賬號(hào)信息泄漏風(fēng)險(xiǎn)降到最低。再不同的場(chǎng)景下部署階段會(huì)補(bǔ)充額外步驟如果是Web服務(wù)可能是運(yùn)行數(shù)據(jù)庫(kù)遷移腳本和服務(wù)滾動(dòng)更新如果是庫(kù)項(xiàng)目則可能是觸發(fā)下游的依賴構(gòu)建??傊苋詣?dòng)的發(fā)就一定不要讓人手動(dòng)執(zhí)行但“人工審批門”該留的還是應(yīng)該留著例如發(fā)布到生產(chǎn)這種動(dòng)作我始終保留一個(gè)手動(dòng)確認(rèn)的步驟。4. 實(shí)操過程用GitHub Actions搭一條完整流水線4.1 初始化項(xiàng)目結(jié)構(gòu)和基礎(chǔ)配置文件為了直接抄作業(yè)我用一個(gè)名為demo-py-service的假設(shè)服務(wù)項(xiàng)目做示例。項(xiàng)目的結(jié)構(gòu)大概是這樣的demo-py-service/ ├── .github/ │ └── workflows/ │ ├── ci.yml │ └── release.yml ├── src/ │ └── demo_py_service/ │ ├── __init__.py │ └── app.py ├── tests/ │ └── test_app.py ├── pyproject.toml ├── poetry.lock ├── README.md └── .pre-commit-config.yaml我習(xí)慣用src/布局而不是根目錄布局這樣能更早發(fā)現(xiàn)打包時(shí)的路徑問題。pyproject.toml里集中配置工具鏈避免散落多個(gè)配置文件。4.2 寫出一條最基礎(chǔ)的CI工作流一條最基礎(chǔ)的CI工作流目標(biāo)是完成“安裝依賴、靜態(tài)檢查、跑測(cè)試、構(gòu)建產(chǎn)物”四步。下面這個(gè)配置可以直接放到ci.yml里name: ci on: push: branches: [ main ] pull_request: env: PYTHON_VERSION: 3.12.5 jobs: verify: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkoutv4 - name: Set up Python uses: actions/setup-pythonv5 with: python-version: ${{ env.PYTHON_VERSION }} cache: pip - name: Install dependencies run: | pip install --upgrade pip pip install -r requirements-dev.txt -r requirements.txt這個(gè)文件里的第一個(gè)重點(diǎn)是把Python版本明確寫為3.12.5。我曾經(jīng)遇到過只寫3.12結(jié)果今天跑在3.12.3、下周跑在3.12.7的情況隨后某個(gè)底層庫(kù)行為突變導(dǎo)致一道隨機(jī)失敗排查了大半天。明確到補(bǔ)丁版本就能避免這種鬧劇。cache: pip這個(gè)參數(shù)是setup-python內(nèi)置的它會(huì)根據(jù)runner上鎖定的文件生成緩存。但我有自己的依賴文件習(xí)慣所以后面會(huì)更喜歡用更強(qiáng)的緩存步驟去緩存整個(gè).venv目錄。4.3 分步解析測(cè)試、靜態(tài)檢查和類型檢查繼續(xù)完善驗(yàn)證階段。習(xí)慣上我會(huì)把質(zhì)量檢查分成三個(gè)steplint、typecheck和test。這樣做的目的是讓失敗日志清晰你能一眼看出是哪個(gè)環(huán)節(jié)出了問題而不是“安裝依賴失敗”的報(bào)錯(cuò)把所有信息壓在最底下。- name: Lint with ruff run: ruff check src tests - name: Type check with mypy run: mypy src - name: Test with pytest run: | pytest -n auto tests這三個(gè)step放在同一個(gè)job里好處是復(fù)用同一個(gè)Python緩存環(huán)境避免了反復(fù)安裝解釋器和依賴。如果希望不同檢查各自拆開并行就需要承擔(dān)多次安裝依賴的額外時(shí)間開銷。對(duì)于中小項(xiàng)目我建議保持在同一job里省時(shí)省事。4.4 矩陣測(cè)試多版本、多依賴組合一次跑通矩陣測(cè)試是PythonCI里性價(jià)比極高的一個(gè)功能。它會(huì)對(duì)多組組合做叉積驗(yàn)證比如同時(shí)驗(yàn)證Python 3.10、3.11、3.12三個(gè)版本以及可選依賴的有無兩種情況。配置大概是這樣的strategy: fail-fast: false matrix: python-version: [3.10, 3.11, 3.12] dependency-profile: [minimal, latest]我會(huì)設(shè)置fail-fast: false。默認(rèn)的fail-fast: true會(huì)在第一個(gè)組合失敗時(shí)取消其他所有還在運(yùn)行的任務(wù)表面上節(jié)省了資源實(shí)際上會(huì)丟失很多關(guān)于兼容性邊界的反饋信息。取消之后即使某一版本掛了其他組合還會(huì)繼續(xù)跑完很快能看出是全掛還是一個(gè)版本單獨(dú)掛這在排查Python版本兼容問題時(shí)真的能救命。4.5 緩存優(yōu)化把venv放進(jìn)去setup-python的cache: pip對(duì)大多數(shù)項(xiàng)目夠用但如果依賴較多安裝過程依然耗時(shí)。我的優(yōu)化策略是加入一個(gè)顯式緩存步驟緩存虛擬環(huán)境目錄。示例配置- name: Cache virtualenv uses: actions/cachev4 with: path: .venv key: ${{ runner.os }}-venv-${{ env.PYTHON_VERSION }}-${{ hashFiles(requirements*.txt) }} restore-keys: | ${{ runner.os }}-venv-${{ env.PYTHON_VERSION }}這里將緩存鍵和依賴鎖定文件的哈希值綁定。哈希變了就會(huì)重新創(chuàng)建緩存哈希不變則直接恢復(fù)命中后依賴安裝速度快得離譜。要注意如果緩存命中的是半個(gè)舊環(huán)境某些字段會(huì)殘留做好重建策略很重要。我在requirements-dev.txt里的依賴變更比較頻繁所以會(huì)把requirements文件和鎖定文件一起計(jì)入哈希盡量提高緩存匹配精度。還有一點(diǎn)值得提醒如果用的是poetry緩存的就是~/.cache/pypoetry或者項(xiàng)目的.venv鍵中最好也加上poetry.lock的哈希因?yàn)殒i定文件才是真正決定依賴集合的東西pyproject.toml影響相對(duì)間接。4.6 合并門禁與自動(dòng)發(fā)布流程CI跑完只是第一步想讓流水線真正發(fā)揮作用就要在GitHub分支保護(hù)規(guī)則里把CI設(shè)為必過檢查。具體是在倉(cāng)庫(kù)的Settings里針對(duì)目標(biāo)分支啟用“Require status checks to pass before merging”勾選verify這個(gè)job并禁止跳過。這一步非常關(guān)鍵因?yàn)橹灰獩]有強(qiáng)制總會(huì)有人想把代碼“先合上再說”。發(fā)布階段我單獨(dú)寫在release.yml中用Git標(biāo)簽來觸發(fā)name: release on: push: tags: - v* jobs: build-and-publish: runs-on: ubuntu-latest environment: production steps: - name: Checkout uses: actions/checkoutv4 - name: Set up Python uses: actions/setup-pythonv5 with: python-version: 3.12.5 - name: Build package run: python -m build - name: Install from built package run: | python -m venv /tmp/check-env /tmp/check-env/bin/pip install dist/demo_py_service-*.whl /tmp/check-env/bin/demo-service --help - name: Publish to PyPI env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }} run: twine upload dist/*這個(gè)工作流里我最看重的是“從構(gòu)建產(chǎn)物安裝并冒煙驗(yàn)證”這一步。很多人構(gòu)建完就直接上傳結(jié)果用戶在安裝時(shí)才發(fā)現(xiàn)包的元數(shù)據(jù)有問題。加一個(gè)干凈環(huán)境安裝驗(yàn)證能擋住大量低級(jí)錯(cuò)誤。發(fā)布時(shí)通過環(huán)境變量讀取secret比在命令行里傳明文密碼安全得多。4.7 用act在本地模擬GitHub Actions雖然GitHub Actions已經(jīng)在云端托管但迭代測(cè)試工作流本身偶爾還是要在本地跑一下。act是一個(gè)在Docker容器里模擬GitHub Actions運(yùn)行環(huán)境的開源工具。用它調(diào)試工作流文件非常方便不用每次測(cè)試配置都推一個(gè)commit到遠(yuǎn)端去觸發(fā)CI。使用方式也很簡(jiǎn)單act -j verify它會(huì)自動(dòng)讀取.github/workflows/ci.yml在本地容器中按步驟執(zhí)行。需要注意act需要在本地能正常拉取Docker鏡像且部分action如actions/github-script或涉及secrets的操作需要額外配置。不過用它調(diào)試語法錯(cuò)誤、確認(rèn)緩存策略、觀察依賴安裝過程確實(shí)能顯著提高效率。5. 常見問題與排查技巧實(shí)錄5.1 我踩過的六個(gè)典型坑第一個(gè)坑是“本地成功CI失敗”。這類問題90%都出在依賴或環(huán)境的差異上。排查時(shí)我會(huì)先在本地執(zhí)行一個(gè)和自己構(gòu)建環(huán)境幾乎平行的虛擬環(huán)境然后逐步對(duì)比pip freeze的差異。這個(gè)過程中的小技巧是查看CI日志里的安裝步驟GitHub Actions日志會(huì)完整記錄解析出的依賴版本能直接幫你快速看出差距。第二個(gè)坑是“測(cè)試隨機(jī)失敗”。大多數(shù)和并行或全局狀態(tài)有關(guān)。解決思路是按上一節(jié)提過的方法先加--dist loadgroup或者在代碼里清理資源上下文。我還會(huì)在pytest里啟用--strict-markers防止有些標(biāo)記被悄悄吃掉而不生效。第三個(gè)坑是“緩存永遠(yuǎn)不命中”。這種情況通常是哈希匹配邏輯寫錯(cuò)了。檢查一下當(dāng)前分支對(duì)比默認(rèn)分支的哈希是否變化以及緩存鍵里的文件路徑是否正確。還有一個(gè)容易被忽略的點(diǎn)restore-keys不會(huì)自動(dòng)把最新緩存存回去如果你希望每次執(zhí)行后更新緩存需要額外調(diào)用actions/cache/save。第四個(gè)坑是“Docker鏡像拉取超時(shí)”。這部分受網(wǎng)絡(luò)影響很大我能給的建議是盡量?jī)?yōu)先使用托管平臺(tái)官方鏡像和自帶action把中國(guó)區(qū)團(tuán)隊(duì)的網(wǎng)絡(luò)情況納入考量之后選擇更合適的鏡像源或者配置鏡像地址。這里不便展開主要是靈活處理。第五個(gè)坑是“發(fā)布時(shí)忘記了測(cè)試”。有很多團(tuán)隊(duì)把release流水線和ci流水線完全打成了兩套發(fā)布時(shí)只跑構(gòu)建和推送結(jié)果發(fā)布出去的代碼沒經(jīng)過測(cè)試驗(yàn)證。我的建議是發(fā)布job里第一步先調(diào)用CI里的測(cè)試job或者直接把完整的驗(yàn)證步驟復(fù)制進(jìn)來寧可慢一點(diǎn)也要保證發(fā)出去的產(chǎn)物是經(jīng)過全套檢查的。第六個(gè)坑是“環(huán)境變量和密鑰泄漏”。這種問題的破壞性很大。風(fēng)險(xiǎn)主要來自兩個(gè)地方一是日志打印時(shí)不小心輸出密鑰二是把密鑰寫在倉(cāng)庫(kù)文件里。我的對(duì)策是在CI配置中禁用調(diào)試模式所有密鑰都用secret管理并且在pre-commit里加一條鉤子掃描類似BEGIN PRIVATE KEY的內(nèi)容。5.2 排查方法從日志到最小復(fù)現(xiàn)排查CI問題時(shí)我們最大的利器其實(shí)是日志但不是只會(huì)翻日志而是要會(huì)看日志。第一步先定位是在哪個(gè)階段掛掉。第二步看這個(gè)階段里的具體命令返回碼以及它前后幾行輸出。第三步嘗試在本地復(fù)現(xiàn)常用的命令就是act或者本地docker容器。如果還不行就在CI里臨時(shí)追加一個(gè)debug步驟把當(dāng)時(shí)的目錄結(jié)構(gòu)、環(huán)境變量和依賴信息全部打印一遍排查完成后記得刪掉。有一個(gè)經(jīng)驗(yàn)我覺得很值得講排查問題時(shí)不要只關(guān)注報(bào)錯(cuò)的那一行還要關(guān)注報(bào)錯(cuò)之前環(huán)境發(fā)生的變化。很多Python依賴錯(cuò)誤都是系統(tǒng)底層庫(kù)發(fā)生變化導(dǎo)致的間接結(jié)果比如某個(gè)二進(jìn)制擴(kuò)展依賴了新版本的GLIBC而基礎(chǔ)鏡像太舊。這種時(shí)候alias到個(gè)pip check往往比警告本身更有用。5.3 一些關(guān)于成本和安全性的額外提醒托管CI按分鐘數(shù)計(jì)費(fèi)所以我們要學(xué)會(huì)把重活拆分。每天跑全套測(cè)試的成本是極高的可以在PR事件上跑快速測(cè)試矩陣在合并到主分支后跑完整且耗時(shí)的集成測(cè)試。這樣既保證了開發(fā)反饋速度又控制了賬單。同時(shí)建議定期清理失效的分支和工作流有些團(tuán)隊(duì)幾十年不清理CI任務(wù)列表一眼望不到盡頭排查問題的時(shí)候很受罪。安全方面除開密鑰泄漏之外還有兩個(gè)容易被忽視的點(diǎn)依賴供應(yīng)鏈漏洞掃描和自動(dòng)化流水線自身的權(quán)限最小化。依賴掃描可以用pip-audit在CI里定期跑開頭如果發(fā)現(xiàn)高危漏洞就讓流水線失敗。自托管Runner更要注意權(quán)限隔離每個(gè)Runner的令牌范圍要最小化不要讓部署墻擋不住一個(gè)漏洞。5.4 常見問題速查表現(xiàn)象常見原因快速處置本地通過CI失敗依賴版本不一致或環(huán)境差異對(duì)比pip freeze鎖定版本測(cè)試并行隨機(jī)失敗全局狀態(tài)或資源爭(zhēng)用用fixture隔離關(guān)閉并行或歸類文件緩存永遠(yuǎn)不命中緩存鍵哈?;蚵窂綄戝e(cuò)檢查哈希文件與path字段安裝依賴極慢外網(wǎng)源延遲或鏡像配置問題配置國(guó)內(nèi)鏡像源或調(diào)整緩存策略構(gòu)建成功安裝失敗包配置缺少資源文件在干凈環(huán)境安裝驗(yàn)證wheel流水線一直等待Runner隊(duì)列擁塞查看Runner日志擴(kuò)容或清理任務(wù)CI結(jié)果和本地不一致測(cè)試依賴額外包未鎖定檢查dev依賴是否完整鎖定6. 心得自動(dòng)化解決的是信任問題我在實(shí)際操作中最深的體會(huì)是CI/CD真正的價(jià)值并不是把測(cè)試自動(dòng)化了那么簡(jiǎn)單而是它建立了一種“可復(fù)現(xiàn)的信任”。當(dāng)團(tuán)隊(duì)每天面對(duì)幾十次提交和合并每一個(gè)綠色勾號(hào)背后都有同一套標(biāo)準(zhǔn)在兜底時(shí)大家才會(huì)放心大膽地重構(gòu)、升級(jí)依賴、調(diào)整架構(gòu)而不是每一步都緊張兮兮地祈禱不要搞壞東西。最后再分享一個(gè)我慣用的小技巧流水線本身也是需要測(cè)試和審查的。工作流文件的變更也要走PR不要把CI配置當(dāng)成只能維護(hù)一次的化石。我會(huì)定期檢查每個(gè)job的作用域、緩存命中率和運(yùn)行時(shí)長(zhǎng)每過一段時(shí)間就把那些只漲經(jīng)驗(yàn)不動(dòng)手的步驟砍掉。越是成熟的流水線越應(yīng)該保持簡(jiǎn)潔不要讓工具本身變成項(xiàng)目的負(fù)擔(dān)。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
搡老女人老妇女AAA一VU麻豆 | 久久侵犯人妻爽爽爽| 欧美白嫩在线放| 午夜αv| 中文字幕AV乱伦| 无码9区| 2020中文字幕在线观看| 亚洲天堂,男人| 中文字幕无码不卡啪啪| 色婷婷丁香| 中文字幕第二页| 久久精品高清AV| 9久精品视频在线观看| 成 人 A V免费视频在线观看| 99热66| 97精品视频在线播放| 人人摸人人干人人拍97| 91日日夜夜| 亚洲国产一区二区入口| 青青伊人这里只有精品| 久久久久成人亚洲国产| 色网亚洲人| 国产久久久9999| 激情熟女12P| 区一二区日韩亚洲乱码av电影| 人人看人人插| 日1区2区3区2020| 亚洲高清无码免费观看视频| 翔田千里AV无码秘 三区| 91天天日| 精品少妇人妻av久久免费| 91少妇香蕉久久精品| 99性爱在线观看| 北野未奈加勒比av| 2001天天操| 日韩无码视频黄色| 欧美亚洲特P| 亚洲色吧网| 国产精品高潮久久AV| 静品嫩模一区二区| 超碰免费人妻人人| 小骚逼被操的爽不爽| 亚洲国产尤物yw在线观看| 一二三卡欧美日韩人妻免费精品| 99色色| 国产精品人妻一区二区| 久久老熟女| 91春色| 亚洲AV不卡在线观看尤物| 色啪网| 日本乱人伦片中文三区| 久久久久婷婷精品av电影| 久久精彩视频| 青青操狠狠撩| 亚洲黄色视频在线观看视频| 亚洲丝袜在线观看| 极品色电影院| 色综合99999| 农村妇女一级二级三级视频| 亚洲成a人在线观看久| 人人操人人肉久久精品| 国产欧美日产一区二区三区 - 国产欧美日 | 夜夜爽爽爽| 激情综合色| 日韩性爱人人爱人人操| 亚洲av无码成电影在线播放| 中日韓欧美高清| 97视频在线播放| 久久一区,青青青青草视频在线播放| 乳欲人妻办公室奶水| 欧美亚洲综合高清在线| 亚洲人综合| 国产传媒日本欧美专区| 日韩女优中文字幕| 北京专精特新企业招聘信息| 99热精品青草在线 | 亚洲一区二区专区-国产丝袜精品丝袜-成人AV| 97资源制服丝袜| 国产一区二区欧美日本| 欧美麻豆成人同性GⅤ在线| 人人干人人操人人爱| 大香蕉淫人| 情色大香蕉| 97鸡把在线视频| 日韩青久久| 欧美高潮| 日韩情色一区二区| 亚洲精品久久久久久久蜜桃臀| 亚洲欧美内射| 日韩猛交| A一区片| 极品销魂美女一区二区| 精品一区二区三区免费古装毛片香港三级日本三级人妇 | 日逼国产| 久久一区二区三区入口| 免费操逼视频下载| 久9热| 综合熟女| 国产五码丝袜屁眼| 久久人妇| 国产超碰欧美| 亚洲天堂资源网| 99re视频这里只有精品| 牛牛AV人人夜夜澡人人爽| 91人精品妻入口| 亚洲91在线播放影院| 看大黄色大片原件| 日本五十路熟女一区二区| 青娱乐久久艹| 国产精品一区人妻精品阁在线| 久7色| 国产欧美一区二区| 男人天堂无码| 亚洲色天| 极品尤物女神在线观看| 超碰久久精品| 中文字幕色AV| 国产精品999aaa| 人人操人人干网页| 热热热热日日漂亮永久永久国产日| 啊啊啊97视频| 无码人妻毛片丰满熟妇精品区| 97在线播放| 91狠狠| 操逼逼中文字幕| 色优久久| 青操影院| 韩国免费播放一级毛片| 精品国产丝袜一区二区三区乱码| 亚洲 欧美都市激情| 少妇被玩视频二三区| 国产精品在线一区二区| 人妻夜夜爽天天爽三区麻豆AV网站| 成人日韩3| 免费观看啪视频| 神马午夜久久久| 3P丝袜熟女 色综合| 免费A片三p视频| 五月丁香影视| 蜜乳av一区二区三区| 91w欧美| 欧美一级A片在线看视频性色| 久久久久久大| 加勒比aⅴ| 天天操人人操狠狠插| 丁香婷婷久久 | 人人操,人人液| 亚洲中文字幕精品久久久久久直播 | 后入福利| 中文字幕一区二区韩| 国产按摩一区二区三区| 午夜福利合集| 久久精品店| 另类av天堂| 国产激情在线| 九月丁香| 美女诱惑久久| 九九人人操| 亚洲高清在线se| 人人操我人人干| 高潮内射在线| 国产免费黄色一级大片| 国产按摩一区二区三区| 久久国内| 日韩中文9| 一区二区三区在线美女| 人妻插插人妻人| 日本一区二区不卡| 日韩情色视频| 成年女人黄网站| 美欧老女人97| 国产亚洲中文不卡二区| 国产人妻一区二区三区欧美毛片| 久久精品福利影院| av久日| 亚洲1区2区三区高清中文字幕| 免费人人搞97| 久久直播国产| 国产精品一区在线播放| 一区二区三区精品黑丝白丝酒店对鸡 | 精品视频免费在线一区| Aa东京男人的天堂| 91高清无码下载| 天美传媒av在线| 婷婷激情五月天小说网| 日韩有码中文字幕女同性恋| 1区2区3区在线视频| 操逼操逼操| 婷婷三区| 欧美日韩国产高清在线一二三区| 嗯嗯不要 视频| 嗯嗯啊中文字幕| 成年无码动漫av片无尽在线| 青青草精品| 日韩av无码网站| 国产偷仑| www.天天干| 亚洲黄片免费在线播放| 97资源免费视频| 国产精品亚洲免费| 97超碰精品| 强奸熟女一区二区三区| 99热综合| 色翁荡息又大又硬又粗又爽| 乱操9999| 粉嫩少妇自慰在线| 久久婷婷热| 精品人妻一区二区三区在| 精品十三区| 五月丁香社区婷婷日韩欧美精品影院| 久久人妻| 物业黑人 AV一区| 99在线精品视频| 亚洲黄片免费在线播放| 国产精品动态一区二区三区四四| 亚洲,欧美,春色,另类| 熟妇综合一区二区三区| 97情超碰色| 久久婷婷视频| 久久久久久久九九九九九九| 黄页网站成人免费| 夜草欧美| 日本免费不卡二区| 99热免费| 国产精品自在线发布| 亚洲天堂男人天堂网| 色狠人在线99| 丁香六月婷婷| 免费观看国产不卡av| 欧美色97| 色香在线| 密臀在线免费观看| 国产人妖视频一区在线观看| 日本一级特级毛片视频| 97伊人超碰| 日本超碰97日韩精品人妻| 天天日天天色| 国产免费永久精品无码| 国产成人精品日本视频| 无套内射人妻在线播放| 久久性生大片免费观看性| 久久久久久久久久久久久女过产乱-少妇高潮一区二区三区喷水-成人AV | 亚洲天堂第一页| 欧美夜夜狠| 欧美黄色片AAAAA| 美女视频尤物网在线看| 五月丁香六月综合缴清无码| 亚洲精品一区二区日本| 96麻豆精品一区二区三区| 超碰97欧美日韩| 欧美A√综合网| 人人爱夜夜爱| 欧美日韩淫加| 欧美中字二区| 国产熟女精品区| 四虎884a| 99re这里| 日韩精品影视| 人妻久久| 啊啊啊啊好爽好舒服一区二区易域| julia ann久久| 加勒比久久av| 精品免费囯产一区二区三区| 久久伊人东京热| 哑洲在线| 大香蕉伊人75| 亚洲天堂精品日韩电影| 免费中文综合精品| 操高情无码| 午夜AV人气不卡| 人妻一区视频| AV中文在线| 人妻久久久久久久久久久久久久久| 婷婷五月天激情小说| 激情第四色| 曰韩精品九九无码| 中文字幕天天天天天| 宅男午夜在线视频| 色哟哟1区2区| 欧美视频一区二区三区| 欧美欧美啪啪视频| 丰满岳乱妇一区二区三区| 亚洲美女自拍偷拍视频| 97人妻碰碰中文无码久热丝袜| 国产亚洲一黄| 国产午夜视频| 亚洲91网| blacked精品一区国产| 在线观看综合精品亚洲| 91亚洲精品青草| 日本一二三高清| 蜜桃臀一区二区aV| 2019天天干| 色综合天天| 在线只有精品| 日韩精品第3页| 日韩成人小视频| 91操操操操| 成年人性爱日韩| 78综合网| 四虎免费在线播放| 以及麻豆国产入口在线观看免费| 国产成人免费观看在线视频| 乱人伦 国语对白:视频直接看| 色女99一级片在线观看| 91久热| 人妻色偷色噜| 五月天激情四射| 国产又大又粗又长视频在线| 亚洲深夜福利| 熟女人妇一区二区三区| 伊人色综合超碰| 超碰97久| 日韩在线观看字幕精品| 久久做97| 成人羞羞视频国产| 五月综合激情网| 学生妹天天看| 日韩熟女乱伦中出| 国产九九久久久精品| 亚洲色图8| 中文字幕在线观看永久| 97这里都是精品| 人人澡人人干| 大香蕉色十月| 久久久久久九九九九九| 国产无套粉嫩白浆在| 日韩中文字幕2020| 欧美人妻一区| 欧美色色人| 天天操夜夜操狠很操| 亚欧美天堂在线| 日韩欧美女求操每天更新| 欧美日韩在线国产在线| 三级网站超变态精品| 亚洲精品久久久久毛片A片拉屎 | 精品无码人妻一区二区免费蜜桃| 精品无码久久久久久久久果冻糖心| 色情五月丁香| 亚洲男人天堂手机版| 亚欧国产无码精品在线| 欧美—性—交—色| 九九av| 国产搭汕a级片| 五月婷婷性爱| 国产午夜在线观看| 色婷婷在线视频精品导航| 91熟女丨91老女人| 日本特黄f c2| 亚洲天天做日日做天天谢日日| 亚洲不卡av在线| 欧美视频一| 啊啊啊啊啊啊好湿好爽视频| 99久久久久久亚洲精品不卡| 高跟伊人julia ann| 免费少妇一区二区| 超碰偷拍| 激情五月天色播| 国产精品久久| 超碰97色色| 26uuu性物| 免费男人的天堂| 日韩AV片| 波多野结衣一级视频| 日本超碰97日韩精品人妻| 一类av片在线看| 国产精品高朝久久久久久久| 天天舔天天| 青娱乐二区免费| 欧美老妇综合网| 两性色网| 国产精品免费久久久久久久久久| 另类av综合久久| wwwcaobibi| 97亚洲在线| 97人亚洲综合字幕| 国产女性无套 免费观看| 色亚洲欧美| 久jiu久神马影院| 大香蕉www.超碰| 久肏视频字幕| 亚洲中文字幕日产无码久久| 精品亚洲国产成人AV制服丝袜| 大香蕉人妻久久| 亚洲综合113页| 亚洲图片欧洲图片aⅴ| 亚洲丝袜综合| 吊色| 天天综合影院91| 天天躁日日躁XXXXYY| 香蕉视频欧美一卡二卡| 91碰碰| 久久久久密| 日日碰狠狠添天天爽超| 深夜福利黄片| 亚洲图片视频小说| 天天综合网AV91| 国产伦精品一区二区三区视频女| 欧美性爱三区二区| 夜草网站| 国产97色在线| 欧美极品色| 91亚洲欧美色图| 国产毛片精品一区二区色欲黄A片| 日本操逼视频不卡直接放| 中文字幕视频二区| 欧美人人天天网| 欧美 亚洲 制服 精品| 在线综合色| 一个人免费视频观看在线WWW | 色欲日韩欧美在线一区| 国产精品久久久久无码Av网曝门| 精品日韩人妻精品一二三区| 丝袜美腿丝袜| 亚洲男人在线观看天堂| 亚洲清纯综合| 91色人| 人妻少妇精品久久久| 久久久久9久久久久| 成人精品在线| 2010男人的天堂| www.夜夜操| 国产精品青草综合久久| 久久性爱大全| av国产无码| 激情综合网五月婷婷五月天| 亚洲女毛多水多21P| 日日噜噜夜夜狠狠视频无| av网站免费看| 欧洲在线性爱视频| 日本操逼aaaaa| 色综合av综合久久| 色综合V| 欧美自拍偷拍综合图片| 国产精品午夜福利亚洲综合网| 白丝一区| 激情小说图片亚洲首页| 国产精品日韩在线一区| 欧美激情性久久久久久| 一区二区三区高清天码| 波多野结衣先锋影音| 97人人操人人摸人人爱| 日韩av在线播放不卡| 精品v日韩欧美国产| h无码动漫在线观看| 国产综合网站在线播放 | 秋霞影音一区二区三区| 亚洲欧美日韩精品久久久一区二区| 欧美一级国产一级| 国产情侣自拍在线播放| 97天堂| 欧美日韩性感| 香蕉久久精品| 91N综合网在线| 在线观看啊啊啊啊啊| 亚洲Av诱惑| 成 人 A V免费视频在线观看| 韩三级a视频在线观看| 一区二区三区免费岛国片| 亚洲精品乱码久久久久久蜜桃麻豆 | 亚洲精品成人| 欧美黑人猛交春色影视大全| 精品乱码久久久久| 久久精品噜噜噜成人看免欧美大片| 中国熟妇| 人人操人人插人www| 国产又爽又黄| 夜夜狼人妻| 亚洲自拍青操视频| 青娱乐休闲视频在线观看| 成年人三级黄色片视频| 五月天色色网站| 欧美一级欧美三级在线观看| 综合天天。| 久久专区| 蜜乳av首页| 天堂精品小草| 日韩欧美加勒比| 91高清无码下载| 亚洲男人天堂2019| 99福利社| 你懂的在线观看区国产 | 91少妇高潮| 视频国产成人精品日本亚洲18| 唐山老熟妇露脸啪啪叫| 亚洲精品色| 精品久操| 黄片com.| 亚洲情色在线| 久久精品—区二区三区内射| 国语精品内射在线观看| 伊人久久大香线综合无码| 国产精品另类一区大香蕉| 日韩一级久久毛片| 激情五月天网| 深夜激情| 久久‘黄片视频| 欧美在线啊啊啊| 懂色Av| 色色婷婷五月| 91国产丝袜白虎| 亚洲成人性| 日本精品88888888| 日韩一二三区| 夜夜嗨一区二区| 国产一区二区在线看| 国产精品一级特黄aaa大片在线观看| 在线啊啊啊啊| 男人的午夜天堂| 五月婷丁香| 亚洲精品熟妇1区2区3区。| 国产福利在线视频网站| 亚洲美女30b| 成人五月天丁香激情综合| 久久久久成人蜜桃精品| 欧美日韩亚洲天堂| 黑丝少妇| 国产 日韩,欧美 自拍| 99热免费| 上特色A在线| 少妇高潮99p| 九九九热| 91性生活久久久| 日本性爱视频一级| 北京美女一区二区| 乱伦图一区| 最新9久久久9免费视频| 人人色人人操在线| 日本不卡一二区| 嗯嗯嗯好爽| 国产女人视频三四五区| 一区=区三区视频| 久久草草亚洲蜜桃臀| 今日头条成人一区二区三区四虎精品| 曰韩精品九九无码| 97亚洲欧美| 日韩影片中文字幕一区二区三区| 免费啪啪av| 国产女人9999| 久热无码| 人人模人人看| 欧美 亚洲 综合 制服 另类| 黄色av一区二区在线| 中文字幕一区二区无码成人 | 怡红院亚洲怡春院av| 毛片电影一区二区三区| 亚洲超碰97| 欧美日韩人人早| 日韩欧美aⅴ综合网站发布| 欧美最大综合网| 不卡啪啪视频| 黄片www视频免费| 粉嫩AV输入| 久久女婷| 隔壁邻居波多野结衣中文字幕| 天天热精品| 色97| 啪啪啪精品视频| 久这精品中文在线观看视频| 日韩欧美丝袜诱惑| 欧美精品999| 欧美乱伦专区| 国产精品97超碰| 久久免费老司机精品| 九九综合久久中文字幕| 97视频播放| 激情终合网| 性爱综合网| 久久久99免费| 熟妇人妻精品一区二区| 国产噜噜噜噜噜久久久久久久久| 亚洲综合成人网| 精品人成视频在线观看| 大逼色网站| 亚洲视频二区| 中文字幕一区 二 区 三 四 五 区日 日 骚 | 激情综合网五月婷婷五月天| 久久69| 青青操视频在线| 欧美日韩夜夜| 美日韩成人| 欧美另类精品xxxx| 人妻少妇久久中文字幕一区二区 麻豆 | 日本一区三级韩国| 色综合色欲色综合色综合色综合| 九九视频黄色片| 丰满人妻-区二区三区免费看| AV99热18这里只有精品| 无码一区二区三区四区五区六区七区八区九区十区视频 | 欧美日韩中文字幕不卡| 亚洲欲| 午夜精品久久久99| 伊人影院在线理论播放| 五月天综合| 国产成人无码网站在线视频| 天天看天天综合成人网| 无码抄逼网| 亚洲AV无码翔田千里网站| 伊人天天久久动态图| 人爽不卡视频| 噜噜噜噜久久久精品免费| 夜夜操夜夜高潮夜夜爽国产精品区| 韩国三级三级BD在线| 欧美中文字幕男人天堂久久精品| 污啪啪啪视频| 男人的天堂2019AV| 亚洲影视综合网| 日韩三级一区| 久久婷婷色综合一区二区三区| 超碰免费在线| 日产狠狠干| 大香蕉亚洲中文| 国产一区二区三区中文字幕| 天天日日舔舔| 人人爱夜夜爱| 天天天天做夜夜夜夜做| 青娱乐手机日韩在线视频| 欧美日韩亚洲五月天婷婷| 女人的天堂大香蕉网| 淫骚熟女一区二区三区| 亚洲日韩东京热一区| 熟妇高潮精品一区二区三区下载| 成人久久久精品| 4虎在线视频| 97se亚洲| 日本影视久久免费| 欧美性生活免费网| 亚洲强奸乱伦影视网| 国产一区二区啪啪视频| 午夜人妻精品综合在线| 一牛影视久久久一区二区三区| julia在线观看久久| 色大师网站www永久网站视频| 四虎国产成人精品免费一女五男| 97爱b| 日韩成人人妻网站| 久草成人| 无码国产Av| 欧美黄色片AAAAA| 国产不卡精品91| 久久久∴| 夜夜欧美| 国产理论视频在线播放| 婷婷五月天色| 裸模AV女优| 偷拍亚洲情色| 国产在线视频午夜精华在| www.99中文字幕| 91狠狠综合久久| 综合激情97| 人人操 欧美| 亚洲国产精品无码AV久久久| 九九精品网| 18精品一区| 欧美综合在线91| 中文字幕熟女人妻丝袜丝| 天天日夜干| 国产综合在线视频网站| 性爱av网站| juliaann精品熟女一区| 天美一区在线| 超碰成人人人爽人人爽| 欧美日韩国产中文精品字幕自在自线| 五月丁香激情综合网| 麻豆天美制片厂网站视频| 综合性视频99| 大屁股人妻女教师撅着屁股| 国产亚洲精品第一最新| a男人的天堂| 久久久精品,3| 99热99在线播放激情| 日韩在线视频1234| 国产一区二区在线看| 91搞逼视频| 大稥蕉免费视频这里只有精品| 人妻素股| 久久久一区二区三区三州| 天天天天操| 激情综合网一盗摄| 囯产精品久久久久久久久久梁医生| 色情五月婷婷| 四虎在线观看网站| 久久透逼视频| 九九热精品在线| 日天天九九天堂666| 国产女人与拘做受视频免费| 中文字幕精品丝袜| 60秒不遮不挡| av资源在线播放天堂| 欧亚成人在线视频| 丰满美女一级毛片在线播放| 欧美拳交在线播放| 蜜桃传媒视频第一区入口在线看| 双插性欧美一二三区| 国产传媒1234区| 亚洲网站一区二区在线| 97中文超碰| 久久一区二区蜜桃| 五月天色五月| 人爽不卡视频| 啊…啊…操我用力操我| 男人天堂新在线| 婷色五月| 亚洲日韩美女丝袜美腿人妻视频| 天天爽天天操| 欧美激情精品| oumeisetu综合| 少妇综合| 九月AV| 日韩成人精品| 97在线观看免费视频l| 国产家庭乱伦性爱视频| 清清草影| 亚洲乱码国产乱码精网站| 99在线啪| 97色色婷婷| 精品无吗m| 97高清啪啪| 日韩性爱1级片视频| 成人久久久精品| 国产1769在线| 少妇淫妇久久久久久久| 97二区四区| heyZO天然素人无码AⅤ专区| 人妻少妇色综合| 亚洲砖码砖专无区2023| 国产sv美女内射| 毛片视频白嫩| 99在线无码精品秘 入口黑人| 久久网亚洲| 99热只有| 伊人操你| 亚洲久久东京热一二三四五区视频| 操我无码| 国产精品香蕉| 日韩精品怡红院| 激情av| 五月天婷婷在线看| 麻豆区久久久久亚| 日本在线不卡123| 女人被男人桶爽视频网站| 亚洲欧美内射| 婷婷国产精品九区| 亚洲砖码砖专无区2023| 91天天综合日韩欧美| 九九成人精品| www.99在线| 亚洲无码超碰免费| 人妻少妇精品无码专区二区密桃| 日韩国语字幕| 国产AV毛片| 中文字幕在线免费观看 | 大香蕉92| 久久久久9久久久久| 无色无码| 韩国免费播放一级毛片| 欧美在线干| 色综合加勒比四四季| 午夜男女爽爽爽在线视频 | 色啪网| 十八岁啪啪视频免费看| 老女人综合网| 成人日本片久久久蜜桃| 久久av色| 国产欧美伊人| 手机看av网站在线看| 午夜福利国产欧美日韩夜夜| 精品日韩产品在线,日韩在线不卡视频,欧美日韩免费专区/久, | 色婷婷蜜臀av| 五月开心网| 亚洲色 国产 欧美 日韩| 久久久久久久强迫| 91精品网站| 久久99久久99精品天美传媒棢·纸:. | 婷婷激情五月| 肉嘟嘟www视频在线观看高清| 青娱乐福利99| 亚洲人妻在线精品| 97chaopengongkai| 青青草大香蕉视频| 日日嗷| 亚洲性感丝袜诱惑在线观看| 亚洲综合图色在线| 97中文字幕色| 欧美内射少妇| 伊人色综合超碰| 欧美日韩人人精品| 天美av在线观看| 九九热精品| 九九色热| 五月婷婷综合网| 91狠狠综合久久久久久| AA丁香综合激情| 99热这里是精品| 欧洲色色| 91久青| 亚洲色图a| 超碰碰97| 龙兴卡官方查询| 久久精品国产精品| 校园春色家庭伦理欧美激情| 精品视频久久区| 丰满少妇精品一区二区| 伊人嫩草| 亚洲天堂另类| 一区二区三区不卡视频| 精品福利| 1000部熟女视频在线观看| 国产精品免费1区2区视频| 91久久免费视频互動交流| 国产一区二区免费福利片| 国产隔壁老王影院在线| 性影在线视频| 人人透人人操| 丰满人妻-区二区三区免费| 黄页18禁| 性性久久| 老鸭窝成人| 亚洲精品99999| 女人与公拘交酡2020视频| 多毛小伙内射老太婆| 五月天婷精品激情| 乱精品一区字幕二区| 精品乱子一区二区三区99| 狠狠躁日日躁夜夜躁A| 青青草在线视频播放器| 国产熟妇 码视频户外直播| 欧美激情性久久久久久| 丰满人妻一区二区三区大胸懂色| 99热精品在线| 国产a级精品| 91网站18+| 日本精品五区| 一线黄色免费性爱片| 柠檬AV导航| 亚洲色图 欧美热图 清纯唯美 另类自拍 | 国产深夜福利| 新久久AV| 人妻啊啊人妻啊| 98精品国产乱码久久久久久| 午夜欧美精品久久久| 久久日韩精品一区二区| 国产精品久久伊人| 夜夜高潮夜夜爽高清视频一| 中文无线日韩一区| 欧美日韩国产成人高清| 国产亚洲日本精品在线| 久久一二区四| 91高清欧美| 亚洲综合另类小说色区亚洲成av人片在www| 日本在线播放不卡一区| 蜜臀AV一区二区三区激情综合| 懂色av中文字幕一区二区三区天美| 91丝袜在线观看| 日韩性爱播放| 精品人妻一区二区乱码一区二区| 一区二区三区一亚洲中文字幕、综合区灬 | 国产日韩在线播放av| 中亚精品极乱| 中文字幕色AV| 99re公开精品免费视频| 亚洲中文制服诱惑| 久久久极品| 伊人影院综合是一个与深夜成人在线| 青青草在线成人视频| 一二三区视频在线观看| 免费观看的黄色的网站| 中文字幕88av在线| 男人午夜天堂| 亚洲综合色网| 亚洲色图日韩丝袜制服一区二区五月在线 | 青草av在线| 96精品一区| 日韩精品人妻一| av午夜玫瑰| 襙一襙| 日本人妻一区二区| 99re黄 | 中国黄色特级精品一区二区三区片| 肏逼视频日本| 综合色图,成人综合网| 新91视频.cmp| 欧美中出1| 中文字幕熟女人妻丝袜丝| 国产精品久久久久久久毛片1| 精久久久91| 懂色中文一区二区三区| 麻豆AV96熟妇人妻| 国产在线观看91精品一区| 性欧美体内射精| 日韩三级在线观看网站| 日本天天人人狠狠在线日美女| 97超碰欧美手机| 日韩在线76| 黄片www视频免费| 伊人久久青青草| 亚洲国产美女久久久久| 中文字幕视频2区| 日本性感人妻91| 青青草伊人久久| 国产欧美成人第一页在线观看| 欧美日韩国产电影| 午夜福利在线合集| 91青青在线视频| 狼人久草| 男人的天堂2019| 欧美久久婷| 人人妻人人爽 97人人看碰人免费公开视频| 96AV久久久| 天堂俺去俺来也www久久婷婷| 97视频900| 国模精品娜娜一二三区 | 操屄不卡视频| 97精品在线视频| 快点操死我| 岛国色情视频在线观看| 欧亚韩国999| 亚洲久热| 精品国产三级av韩国在线| 99热 按摩 日韩| 人人插人人搞人人操| 亚洲欧美97| 色爱欲亚洲| www黄片免费看com| 国产精品一区二区三| 二对二中文字幕。| 欧美一区二区三区日韩| 精品国产乱码久久| 亚洲熟女乱综合一区二区三区| 国产视频不卡在线观看| 热热色中文无码| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 国产女人和拘做爰视频 | 日韩小电影| 亚州综合AⅤ| 久热无码| 最新国内自拍av免费| 性欧美| 天天做天天爱天天爽AV| 国产97色在线| 成人97人人超碰人人| 精品高清牛人盗摄一区二区三区中文字幕A片免费在线观看 | 东北丰满熟女国产一区| 超碰人妻97| 加勒比人妻综合| 少妇无码太爽| 黑人黄片在线免费观看| 亚洲无码超碰免费| 青青青青青手机视频| 爱爱久久| 亚洲中文字幕妇伦久久| 日本韩欧美在线播放a| 亚洲男人久久综合天堂| 97在线观| 97在线欧| 91l欧美在线| 亚洲国产欧美日韩精品一区二区三区,国产一区二区三区在线看片,欧美性猛交 XXX | 78精品在线| 国产女人9999| 老熟女熟妇| 久久久草成人网站久久久草成人久久久草久久久 | 亚洲中文国际强奸字幕| 思思热国产高清| 丝袜美腿丝袜| 人人摸人人舔一区二区| 日本999精品视频| 日韩AV电影网站| 久久东京国产精品视频| 91九色蝌蚪在线观看| 人人模人人看| 欧美性爱一区二区| 日韩欧美传媒一区国产| 久久久天堂| 欧美性Fer办公室秘书| 试看福利| 上床不卡网站| 大香蕉在线86| 成人无码专区精品视频| 91天天日| 久久久999网站| 国产黄a三级三级三级av在线看 | 超碰久草| 超碰在线1234区| 性欧美精| 日韩丝袜高跟制服在线观看| 亚洲 se图 欧美电影| 少妇被玩视频二三区| 日韩成人色图| 小草精彩毛片| 欧美第一页性| 久久国产99精品72福利| 人妻天天夜夜爽一区二区| 少妇超碰在线| 国产乱码久久| 91在线视频免费中出| 蜜桃久久久久久久| 久久精品72| 亚洲色入欧美| 玖玖爱综合网| 久肏视频字幕| 91中出视频| 另类图片天天影视| 国产精品爆乳懂色蜜乳| 在线亚洲 欧美 日本专区| 天天爽夜夜爽夜夜爽精| 精品毛片av一区二区| 一区操逼日比视频| 92人人操人人| AV 少妇 人妻 偷拍| 九九无码久久精品视频| 玖玖蜜臀资源网| 免费成人在线熟妇网| 久久久国产护士丝袜美腿一| 熟女少妇一区二区三区| 欧美资源| 国产乱伦性爱区| 8050午夜少妇无码| 99视频内射三四| 亚洲国产一区二区三区在线 | 亚洲a色| 亚洲午夜未满十八勿入网站日本又色又爽又黄| 在线a亚洲视频播放在线| 欧美精品久久久久久久丰满| 韩国午夜理伦三级好看| 超碰在线看| 欧美三级免费伊人| 欲女人妻性色av| 97超碰9| 国产亚洲深夜激情| 中文字幕免费看大片| 情色AV电影| 亚洲欧美精品久| 亚洲深夜福利| 亚洲AV成人无码一二三久久| 激情干在线| 欧美少妇熟女| 九九九热精品| 超碰在线一区| 熟女色综合久久| 美女人妻色网站| 任我爽在线视频免费观看 | 色吧综合网| 99re视频这里只有精品| 国产精品ww久久| 欧美日韩一区二区三区四区蜜桃| 婷婷综合五月| 亚州春色| 欧美天天综合网| 中文字幕aⅴ在线视频| http://qxhbdz.com| 人人九九精| 久操操AV电影| Julia在线播放亚洲久久| 亚洲成人妻日韩在线| 日少妇视频| 97任你吞精| 99热 按摩 日韩| 99re免费| 99性视频| 中国的操老妇女| 亚洲国产精品无码AV久久久| 亚洲天堂99| 综合激情一一91| 激情 欧美 亚洲 小说| 欧美 亚洲 综合 制服| 男人的天堂三级| ..日韩av毛片精品久久久| 强奸少妇AV导航网| 日韩有码专区| 中文字幕在线日亚州9| 亚州欧美一区| 国产精品白丝在线播放| 亚洲影视综合网| 国产精品久久久亚洲第一牛牛_在线观看| 黄色电影在线播放综合网站| 91人妻人人妻| 超碰美国| 色婷婷丁香五月| 疯操AV| 日韩AV无码中文一区二区| 欧美页片| 国产精品黑人一区二区三区| AV天天在线观看| 九九九九精品视频| 激情五月天色色网| 久久久久深夜无码| 欧美久久伊人| 久久妇| 日韩欧美俄罗斯A片| 亚洲色图综合网| 多毛小伙内射老太婆| 亚洲区限制级| 在线观看成人性爱免费小视频| 丝袜综合| 午夜超爽| 久久久久久久久久久久九| 乱伦a片视频| 一区二区三区成人| 人干人人人操人人摸| 色综合超碰超| 成人福利视频网| 天天综合,91入口| 香蕉久久国产AV一区二区| 久久黄黄黄| 麻豆国产尤物AV| 91综合在线| 中文字幕乱码人妻一区二区三区,99精品 | 无码WWW免费视频网站| 欧洲亚洲综合| 国产欧美日韩在线不卡第一页| 欧美黑人168页欧美黑人167| 中文字幕在线观看二区三区| 后入合集| 亚洲色吧网| 无码久久国产 | 久久久一区二区三区三州| 在线亚洲精品久久久| 亚洲无吗在线视频| 国产精品久久久午夜夜伦鲁鲁| 超碰人妻在线| 亚洲美女AV无码| 最新中文字幕av| 亚洲欧洲日韩国产自在线| 欧美色91| 自拍盗摄一区| 亚洲无吗在线视频| a啊啊啊啊啊啊啊啊一区二区| 青青网三级视频| 无码高清少妇久久| 久草老司机| 不卡在线一区,精品一区二区三区中| 97欧美资源| 午夜九九| 蜜臀久久99精品久久久老,,| 成人性爱免费播放| 亚州再线| 国产一级αv免费看片| 国产精品久久久久久久久久久久久久吹 | 色综合加勒比| 亚洲性综合| 天美传媒一二三区永久网站| 自拍偷拍草一草| 九九九偷拍| 国产男女无套97| 国内精品伊人久久久久影院会| 白丝av| 97在线视频观看免费| 九九久久首页| 睡产熟女乱伦| 欧美999| 精品女同一区| 2025亚洲男人天堂| 国产成人久久久精品免费AV| 国产在线综合网| 亚春色色| 亚洲情色在线| 亚洲美乱| 伊人久久大香大香线蕉中文 | 伊人久久久日韩一区| www.99热|