ฉันจะปรับใช้ / พุชเฉพาะไดเร็กทอรีย่อยของ git repo ไปยัง Heroku ได้อย่างไร


121

ฉันมีโปรเจ็กต์ที่ใช้Serveและได้รับการควบคุมเวอร์ชันโดยใช้ Git Serve สร้างoutputโฟลเดอร์ที่มีไฟล์คงที่ซึ่งฉันต้องการปรับใช้กับ Heroku

ฉันไม่ต้องการปรับใช้โปรเจ็กต์ Serve เองเนื่องจาก Heroku Cedar stack ดูเหมือนจะไม่ชอบมันมากนัก แต่ที่สำคัญที่สุดคือฉันต้องการใช้ประโยชน์จากการสนับสนุนที่ยอดเยี่ยมของ Heroku สำหรับเว็บไซต์แบบคงที่

มีวิธีปรับใช้โฟลเดอร์ย่อยกับ git remote หรือไม่? ฉันควรสร้าง Git repo ในoutputโฟลเดอร์ (ฟังดูไม่ถูกต้อง) แล้วส่งไปที่ Heroku หรือไม่


1
คุณอาจกำลังมองหาโมดูลย่อย: book.git-scm.com/5_submodules.html
greg0ire

คำตอบ:


220

มีวิธีที่ง่ายยิ่งขึ้นผ่านทางเป็นGit-ทรีย่อย สมมติว่าคุณต้องการพุชโฟลเดอร์ 'เอาต์พุต' เป็นรูทไปยัง Heroku คุณสามารถทำได้:

git subtree push --prefix output heroku master

ตอนนี้ดูเหมือนว่า git-subtree จะรวมอยู่ใน git-core แต่ฉันไม่รู้ว่า git-core รุ่นนั้นได้รับการเผยแพร่แล้วหรือยัง


1
อ้อ แต่ยังคงเป็นทรีย่อย ( ณ วันที่ 1.8.0.2) ไม่รวมติดตั้งผ่านทางคอมไพล์ โชคดีที่การติดตั้งจากแหล่งที่มานั้นรวดเร็วและตรงไปตรงมาหน้านี้ใช้ได้กับฉันบน Mac
dribnet

14
หากคุณต้องการ--forceใช้git push heroku `git subtree split --prefix output master`:master --force. ดูstackoverflow.com/a/15623469/2066546
fiedl

2
แต่วิธีที่ถูกต้องในการพุชแท็กเฉพาะคืออะไร git subtree push --prefix output heroku +refs/tags/v1.0.0:refs/heads/masterฉันคิดว่ามันควรจะเป็น +refs/tags/v1.0.0:refs/heads/master does not look like a refแต่นี้ไม่ได้ทำงานและกลับมาพร้อมกับ ฉันต้องการฟังก์ชันประเภทนี้เพื่อให้สามารถสวมบทบาทกลับไปยังแท็กเฉพาะได้ในภายหลัง วิธีที่ถูกต้องในการทำคืออะไร?
เดนิส

1
ฉันได้รับข้อผิดพลาด 'การอัปเดตถูกปฏิเสธเนื่องจากเคล็ดลับสาขาที่ผลักดันอยู่หลังระยะไกล'
พันธมิตร

2
@ and-dev @Eric Burel ฉันพุชoutputโฟลเดอร์ที่มีอยู่ในdevelopสาขาของฉันไปยังheroku masterสาขาได้สำเร็จโดยไม่จำเป็นต้องระบุdevelop:masterดังนั้นดูเหมือนว่ามันจะถูกส่งไปยังสาขาเป้าหมายที่คุณระบุจากสาขาที่คุณเช็คเอาต์ในปัจจุบัน
cprcrack

10

ฉันเริ่มต้นด้วยสิ่งที่ John Berryman วางไว้ แต่จริงๆแล้วมันอาจง่ายกว่านี้ถ้าคุณไม่สนใจเลยเกี่ยวกับประวัติคอมไพล์ของ heroku

cd bin
git init
git add .
git commit -m"deploy"
git push git@heroku.com:your-project-name.git -f
rm -fr .git

ฉันเดาว่าเป็นทางการgit subtreeเป็นคำตอบที่ดีที่สุด แต่ฉันมีปัญหาในการรับทรีย่อยเพื่อทำงานบนเครื่อง Mac ของฉัน


9

ฉันมีปัญหาที่คล้ายกัน ในกรณีของฉันมันไม่เคยเป็นปัญหาที่จะระเบิดทุกอย่างในที่เก็บ heroku และแทนที่ด้วยสิ่งที่อยู่ในไดเร็กทอรีย่อยของฉัน หากเป็นกรณีของคุณคุณสามารถใช้ bash script ต่อไปนี้ เพียงใส่ไว้ในไดเรกทอรีแอป Rails ของคุณ

#!/bin/bash

#change to whichever directory this lives in
cd "$( dirname "$0" )"

#create new git repository and add everything
git init
git add .
git commit -m"init"
git remote add heroku git@heroku.com:young-rain-5086.git

#pull heroku but then checkback out our current local master and mark everything as merged
git pull heroku master
git checkout --ours .
git add -u
git commit -m"merged"

#push back to heroku, open web browser, and remove git repository
git push heroku master
heroku open
rm -fr .git

#go back to wherever we started.
cd -

ฉันแน่ใจว่ามีวิธีปรับปรุงมากมายดังนั้นอย่าลังเลที่จะบอกวิธี!


+1ขอบคุณ โซลูชันนี้ใช้งานได้ดีหากคุณไม่สนใจเกี่ยวกับบันทึก git บน Heroku คุณสามารถปรับแต่งสคริปต์ด้านบนในกรณีที่มีบางโฟลเดอร์ที่คุณต้องการละเว้นภายในเส้นทางย่อยของแอปพลิเคชันที่จะปรับใช้ ตัวอย่างเช่นฉันไม่ต้องการspecโฟลเดอร์บน heroku ตัวอย่าง Gist
ch4nd4n

+1แต่คุณสามารถทำให้ง่ายขึ้นได้โดยไม่ต้องดึงและรวมเข้ากับ heroku master แต่เพียงแค่git push --force heroku master
MK Safi

4

หลังจากพยายามทำสิ่งต่างๆมานานและยากลำบากและถูกกัดทุกครั้งที่ฉันรู้

เพียงเพราะ Heroku ใช้ที่เก็บ git เป็นกลไกการปรับใช้คุณไม่ควรถือว่าเป็นที่เก็บ git

มันอาจจะเป็น rsync ก็ได้เช่นกันพวกเขาใช้คอมไพล์อย่าวอกแวกเพราะสิ่งนี้

ถ้าคุณทำเช่นนั้นคุณจะเปิดใจรับความเจ็บปวดทุกรูปแบบ วิธีแก้ปัญหาที่กล่าวมาทั้งหมดล้มเหลวอย่างน่าสังเวช:

  1. จำเป็นต้องทำบางสิ่งบางอย่างทุกครั้งหรือเป็นระยะ ๆ หรือสิ่งที่ไม่คาดคิดเกิดขึ้น (การผลักดันโมดูลย่อยการซิงค์ต้นไม้ย่อย ... )
  2. ตัวอย่างเช่นหากคุณใช้เอ็นจิ้นในการโมดูลาร์โค้ดของคุณ Bundler จะกินคุณทั้งชีวิตมันเป็นไปไม่ได้ที่จะอธิบายถึงความไม่พอใจที่ฉันมีกับโปรเจ็กต์นั้นในระหว่างการสืบเสาะหาทางออกที่ดีสำหรับสิ่งนี้
    • คุณพยายามเพิ่มเอ็นจิ้นเป็น git repo link + bundle deploy- ล้มเหลวคุณต้องรวมการอัปเดตทุกครั้ง
    • คุณพยายามเพิ่มเอ็นจิ้นเป็น:path+ bundle deploy- ล้มเหลวทีม dev จะพิจารณา:pathตัวเลือกว่า "คุณไม่ได้ใช้ Bundler กับตัวเลือกอัญมณีนี้" ดังนั้นมันจะไม่รวมกลุ่มสำหรับการผลิต
    • นอกจากนี้การรีเฟรชเครื่องยนต์ทุกครั้งต้องการอัปเดตรางของคุณ stack -_-
  3. ทางออกเดียวที่ฉันพบคือใช้เอ็น/vendorจิ้นเป็นsymlink ในการพัฒนาและคัดลอกไฟล์สำหรับการผลิตจริง

การแก้ไขปัญหา

แอปที่เป็นปัญหามี 4 โครงการใน git root:

  1. api - ขึ้นอยู่กับโปรไฟล์จะทำงานบนโฮสต์ heroku 2 ตัวที่แตกต่างกัน - อัปโหลดและ api
  2. เว็บ - เว็บไซต์
  3. เว็บเก่า - เว็บไซต์เก่ายังคงอยู่ในการย้ายข้อมูล
  4. common - ส่วนประกอบทั่วไปที่สกัดในเครื่องยนต์

โครงการทั้งหมดมีvendor/commonsymlink ที่มองไปที่รากของcommonเครื่องยนต์ เมื่อรวบรวมซอร์สโค้ดสำหรับการปรับใช้กับ heroku เราจำเป็นต้องลบ symlink และ rsync ซึ่งเป็นโค้ดที่จะอยู่ในโฟลเดอร์ผู้ขายของแต่ละโฮสต์ที่แยกกัน

  1. ยอมรับรายชื่อโฮสต์เป็นอาร์กิวเมนต์
  2. เรียกใช้ git push ใน repo การพัฒนาของคุณจากนั้นเรียกใช้ clean git pull ในโฟลเดอร์แยกต่างหากตรวจสอบให้แน่ใจว่าไม่มีการพุชการเปลี่ยนแปลงที่สกปรก (ไม่ได้รับคำแนะนำ) ไปยังโฮสต์โดยอัตโนมัติ
  3. ปรับใช้โฮสต์ในแบบคู่ขนาน - ทุก repo ของ heroku git จะถูกดึงออกรหัสใหม่จะถูก rsynced ในตำแหน่งที่ถูกต้องมุ่งมั่นกับข้อมูลพุชพื้นฐานในคอมเมนต์คอมมิตคอมมิต
  4. ในตอนท้ายเราส่งปิงพร้อม curl เพื่อบอกให้โฮสต์งานอดิเรกตื่นขึ้นมาและหางท่อนซุงเพื่อดูว่าทั้งหมดไปไวน์หรือไม่
  5. เล่นได้ดีกับเจนกินส์ด้วย: D (กดรหัสอัตโนมัติเพื่อทดสอบเซิร์ฟเวอร์หลังจากการทดสอบสำเร็จ)

ใช้งานได้ดีมากในป่าโดยมีปัญหาน้อยที่สุด (ไม่?) 6 เดือนแล้ว

นี่คือสคริปต์https://gist.github.com/bbozo/fafa2bbbf8c7b12d923f

อัปเดต 1

@AdamBuczynski ไม่เคยตรงไปตรงมาขนาดนี้

อันดับแรกคุณจะต้องมีสภาพแวดล้อมการผลิตและการทดสอบอย่างน้อยที่สุด - และกลุ่มของฟังก์ชันเฉพาะที่แย่กว่านั้น - ทันใดนั้น 1 โฟลเดอร์ต้องแมปกับโปรเจ็กต์ heroku เป็นความต้องการขั้นพื้นฐานที่ค่อนข้างดีและทุกอย่างจะต้องมีการจัดระเบียบอย่างใด สคริปต์ "รู้" ว่าคุณต้องการปรับใช้แหล่งที่มาใด

อันดับที่ 2 คุณจะต้องการแชร์โค้ดระหว่างโปรเจ็กต์ - ตอนนี้มาถึงแล้วsync_commonส่วน shennanigans ที่มี symlink ในการพัฒนาถูกแทนที่ด้วยโค้ด rsynced จริงบน Heroku เพราะ Heroku ต้องการโครงสร้างโฟลเดอร์และบันเดิลเลอร์และทับทิมจริงๆทำให้สิ่งที่น่าเกลียดแย่มากถ้าคุณ ต้องการแยกเธรดทั่วไปเป็นอัญมณี

อันดับที่ 3 คุณจะต้องเสียบ CI และมันจะเปลี่ยนวิธีการจัดระเบียบโฟลเดอร์ย่อยและ git repo เล็กน้อยในท้ายที่สุดในกรณีการใช้งานที่ง่ายที่สุดที่คุณจะได้รับจากส่วนสำคัญดังกล่าว

ในโปรเจ็กต์อื่น ๆ ฉันต้องเสียบ Java builds เมื่อขายซอฟต์แวร์ให้กับลูกค้าหลายรายคุณจะต้องกรองโมดูลที่ติดตั้งขึ้นอยู่กับข้อกำหนดในการติดตั้งและสิ่งที่ไม่

ฉันควรพิจารณาสำรวจการรวมสิ่งต่าง ๆ ไว้ใน Rakefile หรืออะไรบางอย่างและทำทุกอย่างในลักษณะนั้น ...


สวัสดี @bbozo คุณช่วยคิดกลั่นกรองโซลูชันของคุณสักหน่อยและทำให้เฉพาะกับกรณีการใช้งานของการปรับใช้โฟลเดอร์ย่อยหนึ่งโฟลเดอร์เฉพาะกับโปรเจ็กต์ heroku ที่เฉพาะเจาะจงและนำสิ่งที่ไม่จำเป็น / เฉพาะสำหรับ Heroku ออกไปทั้งหมด
Adam Reis

ขอบคุณสำหรับการอัปเดตคำตอบของคุณ ฉันคิดว่าฉันจะบิตกระสุนและแยกไคลเอ็นต์และโค้ดฝั่งเซิร์ฟเวอร์ของฉันออกเป็นที่เก็บแยกกัน ไม่เหมาะกับสถานการณ์ของเรา แต่มันจะเอาชนะการผลักดันทรีย่อยที่เราต้องทำตอนนี้และจากสิ่งที่ฉันรวบรวมมาก็จะง่ายกว่าการพยายามใช้ symlink มาก
Adam Reis

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