Comment puis-je déployer / pousser uniquement un sous-répertoire de mon dépôt git vers Heroku?


121

J'ai un projet qui utilise Serve et dont la version est contrôlée à l'aide de Git. Serve crée un outputdossier avec des fichiers statiques que je souhaite déployer sur Heroku.

Je ne veux pas déployer le projet Serve lui-même car la pile Heroku Cedar ne semble pas trop l'apprécier, mais surtout je veux profiter de l'excellent support d'Heroku pour les sites Web statiques.

Existe-t-il un moyen de déployer un sous-dossier sur une télécommande git? Dois-je créer un référentiel Git dans le outputdossier (cela semble incorrect) et le pousser vers Heroku?


1
Vous recherchez peut-être des sous-modules: book.git-scm.com/5_submodules.html
greg0ire

Réponses:


220

Il existe un moyen encore plus simple via git-subtree . En supposant que vous souhaitiez pousser votre dossier `` sortie '' en tant que racine vers Heroku, vous pouvez faire:

git subtree push --prefix output heroku master

Il semble actuellement que git-subtree soit inclus dans git-core, mais je ne sais pas si cette version de git-core a encore été publiée.


1
Oui, mais le sous-arbre n'est toujours (à partir de 1.8.0.2) pas inclus via l'installateur git . Heureusement, l'installation à partir des sources est rapide et simple, cette page a fonctionné pour moi sur mac.
dribnet

14
Si vous avez besoin --force, utilisez git push heroku `git subtree split --prefix output master`:master --force. Voir stackoverflow.com/a/15623469/2066546 .
fiedl

2
Mais quelle est la bonne façon de pousser une balise spécifique. J'ai pensé que ça devrait l'être git subtree push --prefix output heroku +refs/tags/v1.0.0:refs/heads/master. Mais cela ne fonctionne pas et revient avec +refs/tags/v1.0.0:refs/heads/master does not look like a ref. J'ai besoin de ce type de fonctionnalité pour pouvoir revenir ultérieurement à des balises spécifiques. Quelle est la bonne façon de procéder?
denis

1
J'obtiens l'erreur `` Les mises à jour ont été rejetées car une pointe de branche poussée est derrière sa télécommande ''
Ally

2
@ and-dev @Eric Burel J'ai poussé avec succès le outputdossier qui était uniquement présent sur ma developbranche vers la heroku masterbranche sans avoir besoin de le spécifier develop:master, donc apparemment il pousse vers la branche cible que vous spécifiez à partir de votre branche actuellement extraite.
cprcrack

10

J'ai commencé avec ce que John Berryman a dit, mais en fait, cela peut être plus simple si vous ne vous souciez pas du tout de l'histoire de heroku git.

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

Je suppose qu'officiel git subtreeest la meilleure réponse, mais j'ai eu du mal à faire fonctionner subtree sur mon mac.


9

J'ai eu un problème similaire. Dans mon cas, cela n'a jamais été un problème de tout supprimer dans le référentiel heroku et de le remplacer par ce qui se trouve dans mon sous-répertoire. Si tel est votre cas, vous pouvez utiliser le script bash suivant. Mettez-le simplement dans le répertoire de votre application 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 -

Je suis sûr qu'il existe de nombreuses façons d'améliorer cela - alors n'hésitez pas à me dire comment!


+1Merci. Cette solution fonctionne très bien si vous ne vous souciez pas des journaux git sur Heroku. On peut modifier le script ci-dessus au cas où il y aurait des dossiers que vous souhaitez ignorer, dans le sous-chemin de l'application à déployer. Par exemple, je ne voulais pas de specdossier sur heroku. Example Gist
ch4nd4n

+1mais vous pouvez simplifier en ne tirant pas et en ne fusionnant pas dans heroku master et simplementgit push --force heroku master
MK Safi

4

Après un long et dur mois à essayer différentes choses et à me faire mordre à chaque fois que j'ai réalisé,

juste parce que Heroku utilise un référentiel git comme mécanisme de déploiement, vous ne devriez pas le traiter comme un référentiel git

ça aurait pu être rsync tout aussi bien, ils sont allés pour git, ne vous laissez pas distraire à cause de ça

si vous le faites, vous vous exposez à toutes sortes de blessures. Toutes les solutions susmentionnées échouent lamentablement quelque part:

  1. il faut faire quelque chose à chaque fois, ou périodiquement, ou des choses inattendues se produisent (pousser des sous-modules, synchroniser des sous-arbres, ...)
  2. si vous utilisez un moteur par exemple pour modulariser votre code, Bundler vous dévorera vivant, il est impossible de décrire le degré de frustration que j'ai eu avec ce projet pendant la quête pour trouver une bonne solution pour cela
    • vous essayez d'ajouter le moteur en tant que lien de repo git + bundle deploy- échec, vous devez regrouper la mise à jour à chaque fois
    • vous essayez d'ajouter le moteur en tant qu'échec :path+ bundle deploy-, l'équipe de développement considère l' :pathoption comme "vous n'utilisez pas Bundler avec cette option de gemme" donc elle ne sera pas groupée pour la production
    • De plus, chaque actualisation du moteur veut mettre à jour votre pile de rails -_-
  3. la seule solution que j'ai trouvée est d'utiliser le moteur comme /vendorlien symbolique dans le développement, et de copier les fichiers pour la production

La solution

L'application en question a 4 projets dans git root:

  1. api - selon le profil fonctionnera sur 2 hôtes heroku différents - téléchargement et api
  2. web - le site web
  3. web-old - l'ancien site Web, toujours en migration
  4. common - les composants communs extraits dans un moteur

Tous les projets ont un vendor/commonlien symbolique regardant la racine du commonmoteur. Lors de la compilation du code source pour le déploiement sur heroku, nous devons supprimer le lien symbolique et rsync son code doit être physiquement dans le dossier du fournisseur de chaque hôte séparé.

  1. accepte une liste de noms d'hôte comme arguments
  2. exécute un git push dans votre dépôt de développement, puis exécute un git pull propre dans un dossier séparé, en s'assurant qu'aucune modification sale (non validée) n'est automatiquement transmise aux hôtes
  3. déploie les hôtes en parallèle - chaque repo heroku git est extrait, le nouveau code est rsynced aux bons endroits, commité avec les informations push de base dans le commentaire git commit,
  4. à la fin, nous envoyons un ping avec curl pour dire aux hôtes amateurs de se réveiller et de suivre les journaux pour voir si tout est allé du vin
  5. joue également bien avec jenkins: D (push de code automatique pour tester les serveurs après des tests réussis)

Fonctionne très très bien dans la nature avec un minimum de problèmes (non?) 6 mois maintenant

Voici le script https://gist.github.com/bbozo/fafa2bbbf8c7b12d923f

Mise à jour 1

@AdamBuczynski, ce n'est jamais aussi simple.

Premièrement, vous aurez toujours au moins un environnement de production et de test - et un tas de clusters spécifiques à une fonction au pire - tout à coup, un dossier doit être mappé à des projets n heroku comme une exigence assez basique et tout doit être organisé d'une manière ou d'une autre pour que le script "sait" quelle source vous souhaitez déployer où,

Deuxièmement, vous voudrez partager du code entre les projets - vient maintenant la sync_commonpartie, les manigances avec des liens symboliques en développement étant remplacées par du code rsynced réel sur Heroku parce que Heroku nécessite une certaine structure de dossiers et un bundler et des rubygems vraiment vraiment vraiment vraiment les choses très moche si vous veulent extraire les fils communs dans une gemme

Troisièmement, vous voudrez brancher CI et cela changera un peu la façon dont les sous-dossiers et git repo doivent être organisés, à la fin, dans le cas d'utilisation le plus simple possible, vous vous retrouverez avec l'essentiel susmentionné.

Dans d'autres projets, j'ai besoin de brancher des versions Java, lors de la vente de logiciels à plusieurs clients, vous devrez filtrer les modules qui seront installés en fonction des exigences d'installation et autres,

Je devrais vraiment envisager d'explorer le regroupement de choses dans un Rakefile ou quelque chose comme ça et tout faire de cette façon ...


Bonjour @bbozo, cela vous dérangerait-il de condenser un peu votre solution et de la rendre spécifique au cas d'utilisation du déploiement d'un sous-dossier spécifique dans un projet heroku spécifique et de supprimer tout ce qui n'est pas nécessaire / spécifique à Heroku?
Adam Reis

Merci d'avoir mis à jour votre réponse. Je pense que je vais juste mordre la balle et diviser mon code côté client et serveur dans des référentiels séparés. Ce n'est pas idéal pour notre situation, mais cela battra les poussées forcées de sous-arbres que nous devons faire maintenant, et d'après ce que je comprends, ce sera aussi beaucoup plus simple que d'essayer d'utiliser des liens symboliques.
Adam Reis

N'ayez pas peur d'un "script de déploiement", ça paye
bbozo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.