ฉันจะทำให้เจนกินส์ CI เป็นตัวกระตุ้น Git เมื่อกดไปที่มาสเตอร์ได้อย่างไร


205

ฉันกำลังพยายามจัดตั้ง Jenkins-ci สำหรับโครงการที่ใช้ GitHub ฉันได้ตั้งค่า Jenkins ด้วยปลั๊กอินที่เหมาะสมแล้ว ฉันต้องการให้เจนกิ้นส์สร้างสคริปต์เมื่อใดก็ตามที่มีใครบางคนในโครงการผลักดันให้เชี่ยวชาญ จนถึงตอนนี้ฉันสามารถตั้งค่าเพื่อให้มีการเรียกใช้งานบิลด์เมื่อใดก็ตามที่มีคนกดไปที่ใดก็ได้ แต่มันกว้างเกินไป ฉันทำสิ่งนี้กับ hooks บริการรับโพสต์ใน Git

ฉันได้อ่านวิกิพีเดียของเจนกินส์แล้วและแบบฝึกหัดสองสามข้อ แต่รายละเอียดนี้ขาดหายไป ... มันอาจจะเกี่ยวข้องกับการสำรวจหรือไม่ หรือควรจะทำงานในด้าน Git ดังนั้น Git จะกระตุ้นเจนกินส์เมื่อmasterมีการเปลี่ยนแปลงเท่านั้น


3
ผู้เขียนต้นฉบับของเจนกิ้นส์ Kohsuke Kawaguchi อธิบายวิธีการแจ้งเตือนแบบพุชจากที่เก็บโดยใช้ปลั๊กอิน Git plugin Git plugin 1.1.14 ดูkohsuke.org/2011/12/01/…
GeraldScott

คำตอบ:


190

ดังที่ระบุไว้แล้วโดยgezzedในความคิดเห็นของเขาในขณะที่มีวิธีแก้ปัญหาที่ดี (อธิบายไว้ในการเลือกตั้งจะต้องตาย: เรียกเจนกินส์สร้างจากเบ็ด Git ):

  • ตั้งค่าทริกเกอร์บิลด์ของงาน Jenkins เป็นPoll SCMแต่ไม่ได้ระบุกำหนดการ

  • สร้างทริกเกอร์การรับโพสต์ GitHub เพื่อแจ้ง URL

    http://yourserver/jenkins/git/notifyCommit?url=<URL of the Git repository>?token=<get token from git to build remotely>
    
  • สิ่งนี้จะทริกเกอร์บิลด์ทั้งหมดที่สำรวจที่เก็บ Git ที่ระบุ

  • อย่างไรก็ตามการสำรวจความเป็นจริงจะตรวจสอบว่ามีอะไรผลักไปที่สาขาที่ใช้หรือไม่

มันทำงานได้อย่างสมบูรณ์


1
วิธีนี้ใช้งานได้ดีสำหรับฉันเช่นกันคุณสามารถใช้วิธีการเดียวกันกับการติดตั้งในพื้นที่ที่ไม่ดี: cweiske.de/tagebuch/gitorious-post-receive-hook-2.htm
Justin Smith

4
ทำงานร่วมกับตะขอ POST ของ Bitbucket (ไม่ใช่เจนกินส์) เช่นกัน ในการระบุข้อมูลรับรองการตรวจสอบสิทธิ์คุณสามารถใช้ผู้ใช้: password@my.ci.server/git/notifyCommit? url = ... เป็น URL
loevborg

สามารถกำหนดค่าเพื่อให้เจนกินส์สร้างเฉพาะ libs / โครงการที่ได้รับผลกระทบจากการผลักดันล่าสุดไปยัง repo ได้หรือไม่ ไม่ได้สร้างทั้งสาขาอีกหรือ
Croolman

คุณช่วยอธิบายส่วนนี้ได้หรือไม่? "สร้างทริกเกอร์การโพสต์การรับ github เพื่อแจ้ง URL"
dewwwald

ฉันคิดว่า GitHub จะต้องสามารถเข้าถึงตัวอย่างของเจนกินส์ของคุณได้ซึ่งหมายความว่าจะต้องสามารถเข้าถึงได้ทั่วไป เป็นไปได้ไหมที่จะทำงานกับเซิร์ฟเวอร์ Jenkins ที่ไม่ใช่แบบสาธารณะ
A. Murray

33

ขณะที่รุ่น 0.5 ที่ GitHub ปลั๊กอินสำหรับเจนกินส์สามารถเรียกสร้างเมื่อมีการเปลี่ยนแปลงจะถูกผลักไป GitHub


23
@asveikau - คำถามเดิมเป็นเรื่องเกี่ยวกับ GitHub
docwhat

นั่นไม่ใช่ทางออกที่ดีเพราะมันเป็นตัวกระตุ้นการสร้างไม่ว่าสาขาไหนจะถูกผลัก
แชนนอน

ที่จริงแล้วดูเหมือนว่าจะเป็นไปตามตัวระบุสาขาในการตั้งค่าปลั๊กอิน git หากคุณเปิดใช้งาน "Poll SCM" (ไม่จำเป็นต้องมีตารางเวลา)
แชนนอน

1
แม้ว่ามันจะเป็นจริง แต่ก็ยังทริกเกอร์บิลด์ไม่ถูกต้องเมื่อไม่มีเวิร์กสเปซอยู่ ("เวิร์กสเปซออฟไลน์การกำหนดเวลาบิลด์ใหม่เพื่อรับเวิร์กสเปซ (nonexisting_workspace) เสร็จแล้ว ดูได้ที่problems.jenkins-ci.org/browse/JENKINS-18079
แชนนอน

GitHub ปลั๊กอินรายการ Git ปลั๊กอินเป็นพึ่งพา วิกิพีเดียบอกว่า "เมื่อมีการสร้างงานที่ระบุ URL ใต้ 'Github โครงการ' และเลือก Git ระบุ URL ภายใต้หัวข้อ 'การบริหารจัดการรหัสที่มา'. มันบอกว่า 'ทริกเกอร์นี้เพียง kicks Git ปลั๊กอินเลือกตั้งภายใน algo สำหรับเหตุการณ์ที่เข้ามาทุกคนกับ repo จับคู่'. ผม คิดว่านั่นหมายความว่า Poll SCM แบบสำรวจค่อนข้างเหมือนในคำตอบที่ยอมรับ แต่มีตัวเลือกในการตั้งค่า webhook โดยอัตโนมัติและคุณสมบัติอื่น ๆ อีกสองอย่าง
dosentmatter

9

แทนการทริกเกอร์บิลด์จากระยะไกลให้เปลี่ยนการกำหนดค่าโครงการเจนกินส์ของคุณเพื่อทริกเกอร์บิลด์โดยการสำรวจ

เจนกิ้นส์สามารถสำรวจความคิดเห็นโดยพิจารณาจากภายในแบบคงที่หรือตาม URL สิ่งหลังคือสิ่งที่คุณต้องการข้ามบิลด์หากไม่มีการเปลี่ยนแปลงสำหรับสาขานั้น รายละเอียดที่แน่นอนอยู่ในเอกสาร โดยพื้นฐานแล้วคุณเพียงแค่ต้องตรวจสอบตัวเลือก "Poll SCM" เว้นว่างช่วงเวลาที่ว่างไว้และตั้งค่ารีโมต URL ให้กด JENKINS_URL / job / name / polling

หนึ่ง gotcha หากคุณมีสภาพแวดล้อม Jenkins ที่ปลอดภัยไม่เหมือน/buildกัน/pollingURL ต้องมีการตรวจสอบสิทธิ์ คำแนะนำที่นี่มีรายละเอียด ตัวอย่างเช่นผมมี GitHub username:apiToken@JENKIS_URL/job/name/pollingโพสต์การรับเบ็ดไป


8

สำหรับGitLabให้ใช้ขั้นตอนเหล่านี้:

  1. ไปที่การตั้งค่าโปรเจ็กต์→ Web hooks
  2. ป้อน URL "Build Now" จากโครงการ Jenkins ของคุณเป็น URL กิจกรรมพุช:

    http://server.com/jenkins/job/project_name/build?delay=0sec ตัวอย่างเช่น

  3. คลิกAdd Web Hookแล้วtest hook

จากนั้นเมื่อใดก็ตามที่คุณคอมมิชชันให้กับที่เก็บเว็บเบ็ดถูกทริกเกอร์และสร้างการสร้าง อย่าลืมตั้งค่าพื้นที่ทำงานของเจนกินส์เป็นdelete workspace before each buildเพื่อให้คุณได้รับสำเนาใหม่ของรหัสใหม่


2
คุณจะแก้ปัญหาในคำถามเกี่ยวกับการสร้างได้อย่างไรเมื่อผลักดันในสาขาหลัก?
Custodio

4

ไม่เกี่ยวข้องกับ Git แต่ด้านล่างฉันจะช่วยในการกำหนดค่างาน Jenkins ในรายละเอียดกับ Mercurial อาจช่วยผู้อื่นในปัญหาที่คล้ายกัน

  1. ติดตั้งปลั๊กอินทริกเกอร์ URL
  2. ไปที่หน้าการกำหนดค่างานและเลือกPoll SCMตัวเลือก ตั้งค่าเป็น* * * * *
  3. ตรวจสอบตัวเลือก: [URLTrigger] - Poll with a URL. ตอนนี้คุณสามารถเลือกตัวเลือกบางอย่างเช่นการเปลี่ยนวันที่แก้ไขเนื้อหา URL ฯลฯ
  4. ในตัวเลือกให้เลือกเปลี่ยนเนื้อหา URL เลือกตัวเลือกแรก - Monitor change of content
  5. บันทึกการเปลี่ยนแปลง

ทริกเกอร์การเปลี่ยนแปลงที่เก็บ Mercurial โดยเช็คอินการทดสอบบางอย่าง

ดูว่าตอนนี้งาน Jenkins ทำงานโดยตรวจสอบการเปลี่ยนแปลง SCM เมื่อสร้างจะดำเนินการเนื่องจากมีการเปลี่ยนแปลง Mercurial Started by an SCM changeแล้วคุณจะเห็นข้อความ อื่นผู้ใช้ที่เริ่มด้วยตนเอง


3

ฉันหวังว่านี่จะช่วยได้: จะทำให้เจนกินส์สร้าง Git ได้อย่างไร

มันเป็นเพียงเรื่องของการใช้ขดเพื่อเรียกใช้งานเจนกินส์โดยใช้ตะขอ Git จาก Git

คำสั่งcurl http://localhost:8080/job/someJob/build?delay=0secสามารถรันงาน Jenkins ซึ่งsomeJobเป็นชื่อของงาน Jenkins

ค้นหาโฟลเดอร์ "hooks" ในโฟลเดอร์. git ที่ซ่อนอยู่ของคุณ เปลี่ยนชื่อไฟล์ "post-commit.sample" เป็น "post-commit" เปิดด้วย Notepad ลบบรรทัด ": Nothing" และวางคำสั่งด้านบนลงไป

แค่นั้นแหละ. เมื่อใดก็ตามที่คุณทำคอมมิท Git จะทริกเกอร์คำสั่ง post-commit ที่กำหนดไว้ในไฟล์


ฉันสับสนที่นี่กับความคิดเห็นของคุณในตอนแรกเพราะฉันคิดว่าฉันต้องเปลี่ยน "งาน" ใน URL ด้านบนเป็นชื่องาน ฉันยังสับสนเพราะเมื่อฉันกด "รายการใหม่" ในเจนกินส์ฉันตั้ง "โครงการ" ไม่ใช่งานดังนั้นเมื่อคุณอ้างอิง "someJob" ข้างบนฉันไม่ทราบว่าเป็นชื่อโครงการของฉัน ในที่สุดฉันก็ค้นพบ URL ที่ฉันต้องการ: localhost: 8078 / job / codecept% 20tests / build โดยที่ "codecept% 20tests" เป็นชื่อของโครงการของฉัน ขอบคุณสำหรับวิธีการแก้ปัญหาของคุณ
Paul Preibisch

1
ขอบคุณพอล ฉันได้อัปเดตโพสต์บล็อกด้วยหมายเหตุเพิ่มเติมซึ่งกล่าวถึงโซลูชันของคุณ "% 20" จะเป็นประโยชน์กับผู้อื่นโดยเฉพาะ
Nav

3

บูรณาการอย่างต่อเนื่องกับเจนกินส์หลังจากรหัสถูกผลักไปยังพื้นที่เก็บข้อมูลจากคำสั่ง Git / GUI:

  1. สร้างงานในเจนกินส์ด้วยชื่องานเท่านั้นและเลือกประเภทของรูปแบบโครงการ OKคลิก หน้าถัดไปไม่เพิ่มอะไร - Saveเพียงแค่คลิก
  2. ไปที่ที่เก็บ Git ในพื้นที่ที่คุณมีซอร์สโค้ดและนำทางไปยัง.git/hooksโฟลเดอร์
  3. hooksโฟลเดอร์มีไฟล์ไม่กี่คน ตรวจสอบ "post-commit" หากไม่มีอยู่ให้สร้างไฟล์ "post-commit" โดยไม่มีนามสกุลไฟล์:

    C:\work\test\\.git\hooks\post-commit
    
  4. แก้ไขไฟล์ "post-commit" ด้วยคำสั่งด้านล่าง ตรวจสอบให้แน่ใจว่ามีอยู่ในโฟลเดอร์ hooks รหัสต้นทางในเครื่องของคุณ

    curl -u userName:apiToken -X POST http://localhost:8080/jenkins/job/jobName/build?token=apiToken
    

    ตัวอย่าง:

    curl -u admin:f1c55b3a07bb2b69b9dd549e96898384 -X POST http://localhost:8080/jenkins/job/Gitcommittest/build?token=f1c55b3a07bb2b69b9dd549e96898384
    

    5

    userName: ชื่อผู้ใช้ Jenkins

    jobName: ชื่องานของบิลด์

    apiToken: ในการรับโทเค็น API ของคุณไปที่หน้าผู้ใช้ Jenkins ของคุณ (ด้านบนขวาในอินเทอร์เฟซ) มีอยู่ในเมนู "กำหนดค่า" ที่ด้านซ้ายของหน้า: "แสดงโทเค็น API"

  5. ทำการเปลี่ยนแปลงในซอร์สโค้ดของคุณและคอมมิตรหัสไปยังที่เก็บ

  6. งานของคุณhttp://localhost:8080/jenkins/job/Gitcommittest/ควรจะสร้าง


3

คุณต้องระบุสาขา โดยค่าเริ่มต้นมันฟังอะไร ดูบล็อกโพสต์ฮัดสัน: Git และ Maven ปลั๊กอิน


ฉันเพิ่งเซ็ตอัพเจนกินส์ที่ทำงานเพื่อดึงการเปลี่ยนแปลงจากคอมไพล์ในสาขาที่ระบุ ทำงานได้ดี +1
Greg K

ฉันได้ตั้งค่าไว้เช่นกัน สิ่งที่ฉันสังเกตเห็นคือเจนกินส์ได้รับการแจ้งเตือนจากการผลักดัน GitHub ทุกครั้งและทำปฏิกิริยากับมัน แต่ทำตามขั้นตอนการสร้างหากหัวหน้าสาขาเปลี่ยนไป ดังนั้นเราจึงได้รับรายงานบิลด์ปลอมที่มีชื่อว่า "ไม่มีการเปลี่ยนแปลง" คุณสังเกตพฤติกรรมนี้เช่นกันหรือไม่?
Ziggy

คำถามเดิมเกี่ยวกับวิธีการแก้ไขทริกเกอร์ในวงกว้างและไม่จำเป็น หากคุณมีงาน jenkin 5 งานที่มีการกำหนดค่าเดียวกันยกเว้นงานแรกที่รับฟัง master master สาขาที่สองที่ devel สาขาที่สาม FeatureX และอื่น ๆ เมื่อคุณกดสาขา FeatureX เท่านั้นงาน jenkins ทั้งหมดจะถูกเรียกสิ่งที่นำไปสู่ ทำงานมากเกินไปด้วยการสร้างช้ามาก
geoom

2

ปลั๊กอิน Trigger Webhook ทั่วไปสามารถกำหนดค่าด้วยตัวกรองเพื่อให้บรรลุนี้

เมื่อกำหนดค่าด้วย

  • ตัวแปรชื่อและการแสดงออกref$.ref
  • ตัวกรองที่มีข้อความและตัวกรองการแสดงออกเช่น$ref^refs/heads/master$

masterแล้วงานที่จะเรียกทุกผลักดันในการ ไม่มีการสำรวจ

คุณอาจต้องการค่าเพิ่มเติมจาก webhook เพื่อดำเนินการสร้างจริง เพียงเพิ่มตัวแปรเพิ่มเติมด้วย JSONPath เพื่อเลือกสิ่งที่คุณต้องการ

มีบางกรณีการใช้งานที่นี่: https://github.com/jenkinsci/generic-webhook-trigger-plugin/tree/master/src/test/resources/org/jenkinsci/plugins/gwt/bdd


คืออะไร"Achi" ?
Peter Mortensen

มัน / เป็นการสะกดผิด
Tomas Bjerre

คุณจะคว้า $ GITCOMMIT ใน Jenkins ได้อย่างไรดูเหมือนว่าจะเป็นเรื่องไร้สาระกับเว็บบล็อก ไม่สามารถส่งสถานะกลับไปบอกว่าสำเร็จหรือล้มเหลวได้
user3520245

1

ในองค์กรปัจจุบันของฉันเราไม่ได้ทำแบบนี้ แต่ทำทั้งในการพัฒนาและการเปิดตัว / สาขา (เราใช้ Git Flow) เพื่อสร้างภาพรวมการสร้าง

ในขณะที่เรากำลังใช้ไพพ์ไลน์แบบหลายสาขาเราจะทำสิ่งนี้ใน Jenkinsfile โดยใช้ไวยากรณ์{} เมื่อ ...

stage {
    when { 
        expression { 
            branch 'develop'
        }
    }
}

นี่คือรายละเอียดในโพสต์บล็อกนี้: https://jenkins.io/blog/2017/01/19/converting-conditional-to-pipeline/#longer-pipeline


1

คำตอบข้างต้นนั้นถูกต้อง แต่ฉันกำลังพูดถึงพวกเขาที่เป็นมือใหม่ที่นี่เพื่อความเรียบง่ายของพวกเขา

โดยเฉพาะอย่างยิ่งสำหรับการตั้งค่าการสร้างทริกเกอร์สำหรับไปป์ไลน์:

พิจารณาว่าคุณมีสาขา Github สองสาขา: 1.master, 2.dev และ Jenkinsfile (ที่เขียนไปป์ไลน์) และไฟล์อื่น ๆ ที่มีอยู่ในแต่ละสาขา

กำหนดค่าโครงการ Pipeline ใหม่ (สำหรับสาขา dev)

## 1. การรวมโค้ดกับ git-plugin และ cron วิธีการที่ จำเป็นต้องติดตั้งปลั๊กอิน git ที่จำเป็นต้องมีและติดตั้งและกำหนดค่าด้วยชื่อและอีเมลของคุณ

  1. ส่วนทั่วไปช่องทำเครื่องหมายตรวจสอบ - 'โครงการนี้ทำพารามิเตอร์' และเพิ่มชื่อ -BRANCH ค่าเริ่มต้น -'refs / remotes / origin / dev '
  2. บิลด์ทริกเกอร์บิลด์ในส่วน "เช็คบ็อกซ์ - 'โพล SCM' และกำหนดเวลาตามความต้องการในการตรวจสอบคอมมิทเช่น '* / 1 * * * *' เพื่อตรวจสอบทุกนาที
  3. ส่วนคำจำกัดความไปป์ไลน์เลือก - สคริปต์ท่อจาก SCM—> เลือก git—> addRepository URL -> เพิ่มข้อมูลประจำตัว git—> เลือกขั้นสูง -> เพิ่มชื่อ - กำเนิด, RefSpec- '+ refs / heads / dev: refs / remotes / origin / dev '(dev เป็นสาขา github) -> Branches to build - $ {SBRANCH} (ชื่อพารามิเตอร์จากจุดที่ 1) -> เส้นทางสคริปต์ -> Jenkinsfile -> ยกเลิกการตรวจสอบ Lightweightcheckout
  4. ใช้ -> บันทึก

## 2. การรวมโค้ด: github-plugin และวิธี webhook ข้อกำหนดเบื้องต้นควรติดตั้งปลั๊กอิน Github และควรกำหนดค่าเซิร์ฟเวอร์ Github การเชื่อมต่อควรได้รับการทดสอบหากไม่พิจารณาการกำหนดค่าต่อไปนี้

กำหนดค่าปลั๊กอิน Github ด้วยบัญชีบน Jenkins

ส่วน GitHub เพิ่มเซิร์ฟเวอร์ Github หากไม่มี URL API: https://api.github.comหนังสือรับรอง: เพิ่มข้อความลับ (คลิกที่ปุ่มเพิ่ม: เลือกประเภทข้อความลับ) ด้วยค่าการเข้าถึงส่วนบุคคล Token (สร้างจากบัญชี Github ของคุณ -> การตั้งค่า -> การตั้งค่าของนักพัฒนา -> โทเค็นการเข้าถึงส่วนบุคคล -> เพิ่มโทเค็น -> ขอบเขตการตรวจสอบ -> คัดลอกโทเค็น) ทดสอบการเชื่อมต่อ -> ตรวจสอบว่าเชื่อมต่อกับบัญชี Github ของคุณหรือไม่ ข้อมูลรับรองก่อนหน้าสำหรับ 'ความลับร่วมกัน'

เพิ่ม webhook หากไม่ได้เพิ่มในที่เก็บของคุณโดย

  1. ไปที่การตั้งค่าที่เก็บ Github -> เพิ่ม webhook—> เพิ่ม URL
    http: // Public_IP: Jenkins_PORT / github-webhook /
  2. หรือถ้าคุณไม่ได้มีการใช้ Public_IP ngrok ติดตั้งรับรองความถูกต้องรับ IP สาธารณะจากคำสั่ง. /ngrok http 80 (ใช้ jenkins_port ของคุณ) จากนั้นเพิ่ม webhook -> เพิ่ม URL http: // Ngrok_IP / github-webhook /
  3. ทดสอบโดยส่ง payload จากหน้าเว็บและตรวจสอบว่าคุณได้รับสถานะ 200 หรือไม่

หากคุณมีคำขอปลั๊กอิน Github Pull ให้กำหนดค่าด้วย Jenkins URL ที่เผยแพร่

  1. ส่วนทั่วไปช่องทำเครื่องหมายตรวจสอบ - 'โครงการ Github' เพิ่ม URL โครงการ - (ลิงค์ GitHub ลงท้ายด้วย '.git /')
  2. ส่วนทั่วไปช่องทำเครื่องหมายตรวจสอบ - 'โครงการนี้ทำพารามิเตอร์' และเพิ่มชื่อ -BRANCH ค่าเริ่มต้น -'refs / remotes / origin / dev '
  3. Build triggers.section.Check ทำเครื่องหมาย - 'ทริกเกอร์เบ็ด GitHub สำหรับการสำรวจ GITScm'
  4. ส่วนของ Pipeline def'n: เลือก - สคริปต์ Pipeline จาก SCM—> เลือก git—> addRepository URL -> เพิ่มข้อมูลประจำตัว git—> เลือกขั้นสูง -> เพิ่มชื่อ - กำเนิด, RefSpec- '+ refs / heads / dev: refs / remotes / origin / dev '(dev เป็นสาขา github) -> Branches to build - $ {SBRANCH} (ชื่อพารามิเตอร์จากจุดอ้างอิงที่ 1 เริ่มต้น) -> เส้นทางสคริปต์ -> Jenkinsfile—> ยกเลิกการตรวจสอบ Lightweightcheckout
  5. ใช้ -> บันทึก


0

โซลูชันของฉันสำหรับเซิร์ฟเวอร์ git ในพื้นที่: ไปที่ไดเรกทอรีเบ็ดเซิร์ฟเวอร์ git ในพื้นที่ของคุณละเว้น update.sample ที่มีอยู่และสร้างไฟล์ใหม่ชื่อแท้จริงเป็น "update" เช่น:

gituser@me:~/project.git/hooks$ pwd
/home/gituser/project.git/hooks
gituser@me:~/project.git/hooks$ cat update
#!/bin/sh
echo "XXX from  update file"
curl -u admin:11f778f9f2c4d1e237d60f479974e3dae9 -X POST http://localhost:8080/job/job4_pullsrc_buildcontainer/build?token=11f778f9f2c4d1e237d60f479974e3dae9

exit 0
gituser@me:~/project.git/hooks$ 

คำสั่ง echo จะปรากฏขึ้นภายใต้ผลการผลักดัน git ของคุณ, โทเค็นสามารถนำมาจากการกำหนดค่างานเจนกินส์ของคุณเรียกดูเพื่อค้นหามัน หากไม่มีการเรียกไฟล์ "อัปเดต" ให้ลองใช้ไฟล์อื่นที่มีชื่อเดียวกันโดยไม่มีนามสกุล "ตัวอย่าง"

นั่นคือทั้งหมดที่คุณต้องการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.