Stellen Sie ein Projekt mit Git Push bereit


412

Ist es möglich, eine Website mit bereitzustellen git push? Ich habe eine Ahnung, dass es etwas mit der Verwendung von Git-Hooks zu tun hat , um eine git reset --hardauf der Serverseite durchzuführen , aber wie würde ich vorgehen, um dies zu erreichen?


2
Ich vermute, dies würde nur in Situationen gelten, in denen es nur einen Produktionsserver gibt, oder?
Rijk

6
@Rijk Nun, Sie können mit Git gleichzeitig auf mehrere Server pushen, aber sobald Sie dieses Niveau erreicht haben, möchten Sie möglicherweise eine tatsächliche Lösung, keinen solchen Hack.
Kyle Cronin

Ich hatte Erfolg mit Capistrano bei meinen Projekten, das ursprünglich für die Bereitstellung von Ruby on Rails-Anwendungen entwickelt wurde, aber gut mit PHP und anderen Projekten funktioniert.

Übersetzte die Antworten auf ru.so ins Russische: ru.stackoverflow.com/questions/428483/…
Nick Volynkin

Antworten:


287

Ich habe dieses Skript auf dieser Seite gefunden und es scheint ziemlich gut zu funktionieren.

  1. Kopieren Sie über Ihr .git-Verzeichnis auf Ihren Webserver
  2. Ändern Sie auf Ihrer lokalen Kopie Ihre .git / config-Datei und fügen Sie Ihren Webserver als Remote hinzu:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. Ersetzen Sie auf dem Server .git / hooks / post-update durch diese Datei (in der Antwort unten).

  4. Fügen Sie den Ausführungszugriff auf die Datei hinzu (erneut auf dem Server):

    chmod +x .git/hooks/post-update
    
  5. Drücken Sie jetzt einfach lokal auf Ihren Webserver und die Arbeitskopie sollte automatisch aktualisiert werden:

    git push production
    

128
Stellen Sie sicher, dass Sie über eine .htaccess-Richtlinie verfügen, die das .git-Verzeichnis vor dem Lesen schützt. Jemand, der Lust auf URL-Tauchen hat, könnte einen Feldtag mit dem gesamten Quellcode haben, wenn er zugänglich ist.
Jeff Ferland

39
Alternativ können Sie das öffentliche Verzeichnis auch zu einem Unterverzeichnis des Git-Repos machen. Dann können Sie private Dateien haben, von denen Sie sicher sein können, dass sie nicht veröffentlicht werden.
Tlrobinson

3
Dieser Link ist tot. Gibt es einen anderen Link zur Post-Update-Datei?
Robert Hurst

6
Vielleicht bin ich etwas fehlt , aber würden Sie nicht möchten , dass Ihre Produktionsserver (n) ziehen von einem Master - git Repositories Product Zweig. Ich denke, das OP hat nur einen Server? Normalerweise lasse ich meinen Continuous Integration Server die Bereitstellung meiner Site durchführen (einige Tests vor der Bereitstellung ausführen).
Adam Gent

4
Befolgen Sie diese Schritte aus einem Repository, das bereits eine Folge von Commits enthält. Sie können zunächst nicht pushen, da der Hauptzweig bereits ausgecheckt ist. Wenn Sie dann einen alternativen Zweig auf der Fernbedienung auschecken, werden nur die verschiedenen Dateien in das Arbeitsverzeichnis ausgecheckt. Ich erwartete, dass der Haken einen Reset durchführen würde
hart

80

Verwenden Sie die folgende Post-Update- Datei:

  1. Kopieren Sie über Ihr .git-Verzeichnis auf Ihren Webserver
  2. Ändern Sie auf Ihrer lokalen Kopie Ihre .git / config-Datei und fügen Sie Ihren Webserver als Remote hinzu:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. Ersetzen Sie auf dem Server .git / hooks / post-update durch die folgende Datei

  4. Fügen Sie den Ausführungszugriff auf die Datei hinzu (erneut auf dem Server):

    chmod +x .git/hooks/post-update
    
  5. Drücken Sie jetzt einfach lokal auf Ihren Webserver und die Arbeitskopie sollte automatisch aktualisiert werden:

    git push production
    
#!/bin/sh
#
# This hook does two things:
#
#  1. update the "info" files that allow the list of references to be
#     queries over dumb transports such as http
#
#  2. if this repository looks like it is a non-bare repository, and
#     the checked-out branch is pushed to, then update the working copy.
#     This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update". 
git-update-server-info 
is_bare=$(git-config --get --bool core.bare) 
if [ -z "$is_bare" ]
then
      # for compatibility's sake, guess
      git_dir_full=$(cd $GIT_DIR; pwd)
      case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi 
update_wc() {
      ref=$1
      echo "Push to checked out branch $ref" >&2
      if [ ! -f $GIT_DIR/logs/HEAD ]
      then
             echo "E:push to non-bare repository requires a HEAD reflog" >&2
             exit 1
      fi
      if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null)
      then
             wc_dirty=0
      else
             echo "W:unstaged changes found in working copy" >&2
             wc_dirty=1
             desc="working copy"
      fi
      if git diff-index --cached HEAD@{1} >/dev/null
      then
             index_dirty=0
      else
             echo "W:uncommitted, staged changes found" >&2
             index_dirty=1
             if [ -n "$desc" ]
             then
                   desc="$desc and index"
             else
                   desc="index"
             fi
      fi
      if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
      then
             new=$(git rev-parse HEAD)
             echo "W:stashing dirty $desc - see git-stash(1)" >&2
             ( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
             git-update-ref --no-deref HEAD HEAD@{1}
             cd $GIT_WORK_TREE
             git stash save "dirty $desc before update to $new";
             git-symbolic-ref HEAD "$ref"
             )
      fi 
      # eye candy - show the WC updates :)
      echo "Updating working copy" >&2
      (cd $GIT_WORK_TREE
      git-diff-index -R --name-status HEAD >&2
      git-reset --hard HEAD)
} 
if [ "$is_bare" = "false" ]
then
      active_branch=`git-symbolic-ref HEAD`
      export GIT_DIR=$(cd $GIT_DIR; pwd)
      GIT_WORK_TREE=${GIT_WORK_TREE-..}
      for ref
      do
             if [ "$ref" = "$active_branch" ]
             then
                   update_wc $ref
             fi
      done
fi

5
Meine Güte ... schreibe dieses Skript einfach in einer Sprache, die du für die Entwicklung verwendest, sei es PHP, Python, Groovy oder was auch immer! Ich habe diese Liebe zu Shell-Skripten, die (subjektiv) eine ziemlich seltsame Syntax und so wenig funktionale Merkmale haben, nie verstanden.
dVaffection

4
@dVaffection In jedem Fall werden Sie Shell-Befehle schreiben, wenn Sie git verwenden. Also anstatt ein Skript in einer anderen Sprache zu schreiben und ständig zwischen dieser Sprache und der Shell zu jonglieren. Alles in Shell zu schreiben scheint logisch, meinst du nicht auch?
Abderrahmane TAHRI JOUTI

Ich musste 'git config receive.denyCurrentBranch updateInstead' auch auf dem Server ausführen, damit es den Push akzeptieren würde. Ich denke, es liegt daran, dass die Filiale ausgecheckt wurde?
stackPusher

60

Nach vielen Fehlstarts und Sackgassen kann ich dank dieses Artikels endlich Website-Code mit nur "git push remote " bereitstellen .

Das Post-Update-Skript des Autors ist nur eine Zeile lang und seine Lösung erfordert keine .htaccess-Konfiguration, um das Git-Repo wie einige andere auszublenden.

Ein paar Stolpersteine, wenn Sie dies auf einer Amazon EC2-Instanz bereitstellen.

1) Wenn Sie sudo verwenden, um das reine Ziel-Repository zu erstellen, müssen Sie den Eigentümer des Repos in ec2-user ändern, da sonst der Push fehlschlägt. (Versuchen Sie "chown ec2-user: ec2-user repo ".)

2) Der Push schlägt fehl, wenn Sie den Speicherort Ihres amazon-private-key .pem nicht vorkonfigurieren, entweder in / etc / ssh / ssh_config als IdentityFile-Parameter oder in ~ / .ssh / config mit "[ Host] - Hostname - IdentityFile - Benutzer "Layout hier beschrieben ...

... JEDOCH, wenn Host in ~ / .ssh / config konfiguriert ist und sich von HostName unterscheidet, schlägt der Git-Push fehl. (Das ist wahrscheinlich ein Git-Bug)


Ich habe die Schritte in dem Artikel befolgt, den Sie erwähnt haben, und alles hat wie ein Zauber funktioniert. Ich frage mich nur, ob es einige Nachteile in Bezug auf Sicherheit oder Stabilität gibt. Irgendwelche Ratschläge dazu?
xlttj

xl-t: Angenommen, Sie verwenden Git über SSH, würde ich sagen, dass die Gefahr darin besteht, einen Fehler mit Git zu machen. Sie könnten den Autor des Artikels fragen; er beendet es mit "Fragen und Vorschläge sind willkommen." Meine derzeitige (hirntote) Replikationsstrategie besteht darin, Transmit by Panic Software zu verwenden.
Earl Zedd

1
Der verlinkte Artikel hat eine wichtige Anforderung, wenn Sie Hooks verwenden. Die Hooks schlagen fehl, wenn sich .git zufällig im selben Namensschema wie das Arbeitsverzeichnis befindet. dh / foo / bar (Arbeitsverzeichnis) und /foo/bar.git (Barebone-Git-Repository). Stellen Sie also sicher, dass Sie / foo / bar in etwas anderes umbenennen, z. B. /foo/bar.live oder / foo / blah. Falls Sie sich fragen, die genaue Fehlermeldung, die Sie erhalten würden, wenn Ihr Arbeitsverzeichnis denselben Namen wie hat Das Barebone-Repository ist "remote: fatal: Konnte nicht in das ursprüngliche cwd zurückspringen: Keine solche Datei oder kein solches Verzeichnis"
Antony

1
Ich folge nicht, warum Sie einen Post-Deployment-Hook benötigen würden, um ausgeführt zu werden. Wenn Sie die Codeänderungen auf ein Remote-Repo übertragen, ist das Remote-Repo auf dem neuesten Stand. Was vermisse ich?
Charlie Schliesser

1
@CharlieS Was Sie vermissen, ist, dass Sie mit git keinen Zweig in ein Repository verschieben können, in dem dieser Zweig ausgecheckt ist. In diesem Fall besteht die (meiner Meinung nach sehr nette) Antwort darin, zwei Repositorys zu haben: ein nacktes Repo, in das Sie pushen, und ein zweites Repo, dessen Arbeitsverzeichnis über den Hook aktualisiert wird, wenn das nackte Repo gepusht wird.
Ben Hughes

21

Installieren Sie git nicht auf einem Server und kopieren Sie den .git-Ordner dort nicht. Um einen Server von einem Git-Klon zu aktualisieren, können Sie den folgenden Befehl verwenden:

git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project

Möglicherweise müssen Sie Dateien löschen, die aus dem Projekt entfernt wurden.

Dadurch werden alle eingecheckten Dateien kopiert. rsync verwendet ssh, das sowieso auf einem Server installiert ist.

Je weniger Software Sie auf einem Server installiert haben, desto sicherer ist er und desto einfacher ist es, die Konfiguration zu verwalten und zu dokumentieren. Es ist auch nicht erforderlich, einen vollständigen Git-Klon auf dem Server zu behalten. es macht es nur komplexer, alles richtig zu sichern.


3
Eine Einschränkung: Es synchronisiert die Dateien, die Sie in Ihrem Arbeitsverzeichnis haben. Ich denke, es kann vermieden werden, ein Skript zu verwenden, das aktuelle Änderungen speichert, alles bereinigt, bereitstellt und dann den Stash zurücksetzt.
mateusz.fiolka

Server sind männlich?
Ian Warburton

12

Im Wesentlichen müssen Sie nur Folgendes tun:

server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"

Ich habe diese Zeilen in meiner Anwendung als ausführbare Datei aufgerufen deploy.

Wenn ich also eine Bereitstellung durchführen möchte, gebe ich ein ./deploy myserver mybranch .


siehe meine Antwort, wie man das Problem löst, wenn Sie einen anderen privaten Schlüssel oder Benutzernamen für ssh benötigen
Karussell

Diese Lösung ist schneller als meine eigene, wenn sie auf mehreren Servern bereitgestellt wird! Drücken Sie einfach auf das Haupt-Repo und ziehen Sie es parallel heraus. Und wenn Sie Ihre Schlüssel nicht für jede Instanz bereitstellen möchten oder können, verwenden Sie den Schlüsselagenten! ssh -A ...
Karussell

1
Es wäre einfacher, wenn Sie eine Anleitung zum Einrichten von SSH-Schlüsseln
beifügen würden,

Die Verwendung von git pullsollte für automatisierte Bereitstellungen vermieden werden, da der Zusammenführungsteil bei Konflikten eine manuelle Bereinigung erfordern kann.
Quinn Comendant

9

So wie ich es mache, habe ich ein nacktes Git-Repository auf meinem Bereitstellungsserver, auf dem ich Änderungen pushe. Dann melde ich mich beim Bereitstellungsserver an, wechsle zum eigentlichen Verzeichnis der Webserver-Dokumente und mache einen Git-Pull. Ich benutze keine Haken, um dies automatisch zu versuchen, das scheint mehr Ärger zu sein, als es wert ist.


Setzen Sie bei Fehlern im neuen Code pro Commit oder während des gesamten Pulls zurück? (Oder ist nur 1 möglich?)
Rudie

1
@Rudie: Wenn Sie Änderungen auf dem Bereitstellungsserver zurücksetzen müssen, können Sie git resetzwischen den neuesten Änderungen zurückkehren (alle Festschreibungen, nicht nur der gesamte Pull). Wenn Sie etwas Bestimmtes zurücksetzen müssen, das nicht das letzte Commit ist, können Sie es verwenden git revert, das jedoch wahrscheinlich nur in Notfällen verwendet werden sollte ( git reverterstellt ein neues Commit, das die Auswirkungen eines vorherigen Commits rückgängig macht).
Greg Hewgill

Nur aus Neugier: Warum denkst du, wären Haken mehr Ärger als es wert ist?
Rijk

@Rijk: Wenn Sie dafür Hooks verwenden, wird das tatsächliche Verzeichnis der Webserver-Dokumente durch einen automatischen Hintergrundprozess geändert. Durch die Anmeldung habe ich mehr Kontrolle darüber, wann Änderungen auf das Dokumentverzeichnis angewendet werden. Es ist auch einfacher zu beheben, wenn etwas schief geht. Hooks sind möglicherweise besser geeignet, wenn Committer keinen ausreichenden Zugriff haben, um sich beim Webserver anzumelden.
Greg Hewgill

Ihr eigentlicher Webapp-Ordner ist also auch ein .git-Repository? Was ist mit dem .git-Ordner, der für die Außenwelt sichtbar ist?
Fernando

9

git config --local receive.denyCurrentBranch updateInstead

In Git 2.3 hinzugefügt, könnte dies eine gute Möglichkeit sein: https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

Sie legen es im Server-Repository fest und es aktualisiert auch den Arbeitsbaum, wenn er sauber ist.

In 2.4 wurden weitere Verbesserungen hinsichtlich des push-to-checkoutHakens und der Handhabung ungeborener Äste vorgenommen .

Beispielnutzung:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

Ausgabe:

a
b

Dies hat die folgenden Mängel, die in der GitHub-Ankündigung erwähnt werden :

  • Ihr Server enthält ein .git-Verzeichnis, das den gesamten Verlauf Ihres Projekts enthält. Sie möchten wahrscheinlich besonders sicherstellen, dass es nicht an Benutzer geliefert werden kann!
  • Während der Bereitstellung können Benutzer vorübergehend auf die Site in einem inkonsistenten Zustand stoßen, wobei einige Dateien in der alten Version und andere in der neuen Version oder sogar halbgeschriebene Dateien vorliegen. Wenn dies ein Problem für Ihr Projekt ist, ist Push-to-Deployment wahrscheinlich nichts für Sie.
  • Wenn Ihr Projekt einen "Build" -Schritt benötigt, müssen Sie diesen explizit einrichten, möglicherweise über Githooks.

Aber all diese Punkte liegen außerhalb des Geltungsbereichs von Git und müssen durch externen Code erledigt werden. In diesem Sinne ist dies zusammen mit Git-Hooks die ultimative Lösung.


Führen Sie zum Festlegen den folgenden Befehl aus: 'git config receive.denyCurrentBranch updateInstead' im Terminal
stackPusher

5

Update: Ich verwende jetzt die Lloyd Moore- Lösung mit dem Schlüsselagenten ssh -A .... Das Drücken auf ein Haupt-Repo und das parallele Ziehen von allen Ihren Maschinen ist etwas schneller und erfordert weniger Setup auf diesen Maschinen.


Ich sehe diese Lösung hier nicht. Drücken Sie einfach über SSH, wenn Git auf dem Server installiert ist.

Sie benötigen den folgenden Eintrag in Ihrer lokalen .git / config

[remote "amazon"]
    url = amazon:/path/to/project.git
    fetch = +refs/heads/*:refs/remotes/amazon/*

Aber hey, womit ist das amazon:? In Ihrer lokalen ~ / .ssh / config müssen Sie den folgenden Eintrag hinzufügen:

Host amazon
    Hostname <YOUR_IP>
    User <USER>
    IdentityFile ~/.ssh/amazon-private-key

Jetzt können Sie anrufen

git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'

(Übrigens: /path/to/project.git unterscheidet sich vom tatsächlichen Arbeitsverzeichnis / path / to / project)


5

Für das Bereitstellungsszenario

In unserem Szenario speichern wir den Code auf github / bitbucket und möchten ihn auf Live-Servern bereitstellen. In diesem Fall funktioniert die folgende Kombination für uns (das ist ein Remix der hoch bewerteten Antworten hier) :

  1. Kopieren Sie über Ihr .gitVerzeichnis auf Ihren Webserver
  2. Auf Ihrer lokalen Kopie git remote add live ssh://user@host:port/folder
  3. Auf der Fernbedienung: git config receive.denyCurrentBranch ignore
  4. Auf der Fernbedienung: nano .git/hooks/post-receiveund fügen Sie diesen Inhalt hinzu:

    #!/bin/sh GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f

  5. Auf der Fernbedienung: chmod +x .git/hooks/post-receive

  6. Jetzt können Sie dort mit schieben git push live

Anmerkungen

  • Diese Lösung funktioniert mit älteren Git-Versionen (getestet mit 1.7 und 1.9).
  • Sie müssen sicherstellen, dass Sie zuerst auf Github / Bitbucket drücken, damit Sie live ein konsistentes Repo haben
  • Wenn sich Ihr .gitOrdner im Dokumentstamm befindet, stellen Sie sicher, dass Sie ihn von außen ausblenden, indem Sie ihn zu .htaccess( Quelle ) hinzufügen :

    RedirectMatch 404 /\..*$


4

Wir verwenden Capistrano für die Verwaltung der Bereitstellung. Wir erstellen capistrano für die Bereitstellung auf einem Staging-Server und führen dann eine rsync mit allen unseren Servern aus.

cap deploy
cap deploy:start_rsync (when the staging is ok)

Mit capistrano können wir im Fehlerfall ein einfaches Rollback durchführen

cap deploy:rollback
cap deploy:start_rsync

Haben Sie die Live-Bereitstellung über rsync in capistrano integriert?
Martin Abraham


1

Klingt so, als ob Sie zwei Kopien auf Ihrem Server haben sollten. Eine bloße Kopie, von der Sie pushen / ziehen können, von der Sie Ihre Änderungen pushen würden, wenn Sie fertig sind, und die Sie dann in Ihr Webverzeichnis klonen und einen Cronjob einrichten würden, um Git Pull jeden Tag oder aus Ihrem Webverzeichnis zu aktualisieren damit.


1

Es ist denkbar, dass Sie einen Git-Hook einrichten, der die Änderungen abruft und auf die PHP-Site anwendet, wenn beispielsweise ein Commit für den "stabilen" Zweig ausgeführt wird. Der große Nachteil ist, dass Sie nicht viel Kontrolle haben, wenn etwas schief geht, und dass dies mehr Zeit für Ihre Tests benötigt. Sie können sich jedoch ein Bild davon machen, wie viel Arbeit erforderlich ist, wenn Sie Ihren Stammzweig in den stabilen Zweig zusammenführen, um dies zu wissen Wie viele Konflikte können auftreten ? Es ist wichtig, alle standortspezifischen Dateien (z. B. Konfigurationsdateien) im Auge zu behalten, es sei denn, Sie möchten nur die eine Site ausführen.

Haben Sie alternativ versucht, die Änderung stattdessen auf die Website zu übertragen?

Informationen zu Git-Hooks finden Sie in der Dokumentation zu Githooks .


1

Meine Einstellung zur Lösung der Christen .

git archive --prefix=deploy/  master | tar -x -C $TMPDIR | rsync $TMPDIR/deploy/ --copy-links -av username@server.com:/home/user/my_app && rm -rf $TMPDIR/deploy
  • Archiviert den Hauptzweig in Teer
  • Extrahiert das Tar-Archiv in das Bereitstellungsverzeichnis im temporären Systemordner.
  • rsync wechselt in den Server
  • Löschen Sie das Bereitstellungsverzeichnis aus dem temporären Ordner.

1

Ich verwende die folgende Lösung von toroid.org , die ein einfacheres Hook-Skript hat.

auf dem Server:

$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/

und installieren Sie den Hook auf dem Server:

$ mkdir /var/www/www.example.org
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
GIT_WORK_TREE=/var/www/www git clean -f -d # clean directory from removed files

$ chmod +x hooks/post-receive

auf Ihrem Kunden:

$ mkdir website && cd website
$ git init
Initialized empty Git repository in /home/ams/website/.git/
$ echo 'Hello, world!' > index.html
$ git add index.html
$ git commit -q -m "The humble beginnings of my web site."

$ git remote add web ssh://server.example.org/home/ams/website.git
$ git push web +master:refs/heads/master

Zum Veröffentlichen geben Sie einfach ein

$ git push web

Eine vollständige Beschreibung finden Sie auf der Website: http://toroid.org/ams/git-website-howto


Löschen Sie auf diese Weise keine vorhandenen Dateien im Repository.
RusAlex

2
Warum git push web +master:refs/heads/masterstatt nur git push web master?
Matthieu Moy

1

Als ergänzende Antwort möchte ich eine Alternative anbieten. Ich benutze Git-FTP und es funktioniert gut.

https://github.com/git-ftp/git-ftp

Einfach zu bedienen, nur Typ:

git ftp push

und git lädt automatisch Projektdateien hoch.

Grüße


0

In einer Umgebung, in der mehrere Entwickler auf dasselbe Repository zugreifen, können die folgenden Richtlinien hilfreich sein.

Stellen Sie sicher, dass Sie eine Unix-Gruppe haben, zu der alle Entwickler gehören, und geben Sie dieser Gruppe das Eigentum am .git-Repository.

  1. Setzen Sie in der .git / config des Server-Repositorys sharedrepository = true. (Dies weist git an, mehrere Benutzer zuzulassen, was für Commits und die Bereitstellung erforderlich ist.

  2. Stellen Sie die Umask jedes Benutzers in seinen bashrc-Dateien auf gleich ein - 002 ist ein guter Anfang


0

Am Ende habe ich mein eigenes rudimentäres Bereitstellungstool erstellt, das automatisch neue Updates aus dem Repo abruft - https://github.com/jesalg/SlimJim - Grundsätzlich hört es auf den Github-Post-Receive-Hook und verwendet einen Proxy, um einen auszulösen Skript aktualisieren.


0

Ich verwende zwei Lösungen für den Post-Receive-Hook:

LÖSUNG VERWENDEN 1

#!/bin/bash 
#  /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 1 

    export GIT_DIR=/git/repo-bare.git
    export GIT_BRANCH1=master
    export GIT_TARGET1=/var/www/html
    export GIT_BRANCH2=dev
    export GIT_TARGET2=/var/www/dev
    echo "GIT DIR:  $GIT_DIR/"
    echo "GIT TARGET1:  $GIT_TARGET1/"
    echo "GIT BRANCH1:  $GIT_BRANCH1/"
    echo "GIT TARGET2:  $GIT_TARGET2/"
    echo "GIT BRANCH2:  $GIT_BRANCH2/"
    echo ""

    cd $GIT_DIR/

while read oldrev newrev refname
do
    branch=$(git rev-parse --abbrev-ref $refname)
    BRANCH_REGEX='^${GIT_BRANCH1}.*$'
    if [[ $branch =~ $BRANCH_REGEX ]] ; then
        export GIT_WORK_TREE=$GIT_TARGET1/.
        echo "Checking out branch: $branch";
        echo "Checking out to workdir: $GIT_WORK_TREE"; 

        git checkout -f $branch
    fi

    BRANCH_REGEX='^${GIT_BRANCH2}.*$'
    if [[ $branch =~ $BRANCH_REGEX ]] ; then
        export GIT_WORK_TREE=$GIT_TARGET2/.
        echo "Checking out branch: $branch";
        echo "Checking out to workdir: $GIT_WORK_TREE"; 

        git checkout -f $branch
    fi
done

LÖSUNG VERWENDEN 2

#!/bin/bash 
#  /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 2

    export GIT_DIR=/git/repo-bare.git
    export GIT_BRANCH1=master
    export GIT_TARGET1=/var/www/html
    export GIT_BRANCH2=dev
    export GIT_TARGET2=/var/www/dev
    export GIT_TEMP_DIR1=/tmp/deploy1
    export GIT_TEMP_DIR2=/tmp/deploy2
    echo "GIT DIR:  $GIT_DIR/"
    echo "GIT TARGET1:  $GIT_TARGET1/"
    echo "GIT BRANCH1:  $GIT_BRANCH1/"
    echo "GIT TARGET2:  $GIT_TARGET2/"
    echo "GIT BRANCH2:  $GIT_BRANCH2/"
    echo "GIT TEMP DIR1:  $GIT_TEMP_DIR1/"
    echo "GIT TEMP DIR2:  $GIT_TEMP_DIR2/"
    echo ""

    cd $GIT_DIR/

while read oldrev newrev refname
do
    branch=$(git rev-parse --abbrev-ref $refname)
    BRANCH_REGEX='^${GIT_BRANCH1}.*$'
    if [[ $branch =~ $BRANCH_REGEX ]] ; then
        export GIT_WORK_TREE=$GIT_TARGET1/.
        echo "Checking out branch: $branch";
        echo "Checking out to workdir: $GIT_WORK_TREE"; 

        # DEPLOY SOLUTION 2: 
        cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR1; 
        export GIT_WORK_TREE=$GIT_TEMP_DIR1/.
        git checkout -f $branch
        export GIT_WORK_TREE=$GIT_TARGET1/.
        rsync $GIT_TEMP_DIR1/. -v -q --delete --delete-after -av $GIT_TARGET1/.
        rm -rf $GIT_TEMP_DIR1
    fi

    BRANCH_REGEX='^${GIT_BRANCH2}.*$'
    if [[ $branch =~ $BRANCH_REGEX ]] ; then
        export GIT_WORK_TREE=$GIT_TARGET2/.
        echo "Checking out branch: $branch";
        echo "Checking out to workdir: $GIT_WORK_TREE"; 

        # DEPLOY SOLUTION 2: 
        cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR2; 
        export GIT_WORK_TREE=$GIT_TEMP_DIR2/.
        git checkout -f $branch
        export GIT_WORK_TREE=$GIT_TARGET2/.
        rsync $GIT_TEMP_DIR2/. -v -q --delete --delete-after -av $GIT_TARGET2/.
        rm -rf $GIT_TEMP_DIR2
    fi
done

Beide Lösungen basieren auf früheren Lösungen, die in diesem Thread verfügbar sind.

Beachten Sie, dass BRANCH_REGEX = '^ $ {GIT_BRANCH1}. $ 'filtert nach den Zweignamen, die mit der Zeichenfolge "master " oder "dev *" übereinstimmen , und stellt den Arbeitsbaum bereit, wenn der gepusste Zweig übereinstimmt. Dies ermöglicht die Bereitstellung einer Entwicklungsversion und einer Masterversion an verschiedenen Orten.

DEPLOY SOLUTION 1 entfernt nur Dateien, die Teil des Repos sind und durch ein Commit entfernt wurden. Es ist schneller als Deployment Solution 2.

DEPLOY SOLUTION 2 hat den Vorteil, dass alle neuen Dateien aus dem Produktionsverzeichnis entfernt werden, das auf der Serverseite hinzugefügt wurde, unabhängig davon, ob sie dem Repo hinzugefügt wurden oder nicht. Es wird immer ein sauberer Betrüger des Repos sein. Es ist langsamer als Deployment Solution 1.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.