Wie gehen Sie mit Konfigurationsdateien in der Quellcodeverwaltung um?


96

Angenommen, Sie haben eine typische Web-App und eine Dateikonfiguration. Jeder Entwickler, der an dem Projekt arbeitet, hat eine Version für seine Entwicklungsboxen, es gibt eine Entwicklungs-, Produkt- und Bühnenversion. Wie gehen Sie in der Quellcodeverwaltung damit um? Diese Datei überhaupt nicht einchecken, mit anderen Namen prüfen oder etwas Besonderes tun?

Antworten:


69

Was ich in der Vergangenheit getan habe, ist eine Standardkonfigurationsdatei, die in die Quellcodeverwaltung eingecheckt ist. Dann hat jeder Entwickler seine eigene Überschreibungskonfigurationsdatei, die von der Quellcodeverwaltung ausgeschlossen ist. Die App lädt zuerst die Standardeinstellung. Wenn die Überschreibungsdatei vorhanden ist, lädt sie diese und verwendet alle Einstellungen der Überschreibung vor der Standarddatei.

Im Allgemeinen ist es umso besser, je kleiner die Überschreibungsdatei ist. Sie kann jedoch immer mehr Einstellungen für Entwickler mit einer sehr ungewöhnlichen Umgebung enthalten.


24

Konfiguration ist Code, und Sie sollten ihn versionieren. Wir stützen unsere Konfigurationsdateien auf Benutzernamen. Sowohl unter UNIX / Mac als auch unter Windows können Sie auf den Anmeldenamen des Benutzers zugreifen. Solange diese für das Projekt eindeutig sind, ist alles in Ordnung. Sie können dies sogar in der Umgebung überschreiben, aber Sie sollten alles versionieren.

Auf diese Weise können Sie auch die Konfigurationen anderer untersuchen, um Build- und Plattformprobleme zu diagnostizieren.


10
+1 absolut für die Betonung, dass die Konfiguration noch versioniert werden sollte
Alexander Bird

Und wenn der Benutzername aus irgendeinem Grund nicht zuverlässig ist, können Sie eine einzelne Datei mit nur einer Zeile haben, die den Namen der Überschreibungskonfigurationsdatei angibt. Auf diese Weise gibt es sehr wenig (wie etwa 10 Zeichen), die nicht versioniert sind. Und die README-Datei könnte erklären, dass Sie diese Datei erstellen müssen.
Alexander Bird

Ich denke immer, dass Konfigurationen vom Code getrennt gehalten werden sollten. Ich habe an Orten gearbeitet, die so viele Konfigurationen für ein Repo erfordern, dass Git nur mit Konfigurationsdateien überfordert ist. Ohne zu sagen, dass Konfigurationen nicht versioniert werden sollten, gehören sie wie ein Artefaktmanager an eine andere Stelle. Config ist kein Code, sondern Einstellungen für Code.
Thomas

Konfigurationsdateien können vertrauliche Informationen wie Kennwörter enthalten, die nicht versioniert werden sollten. Oder möchten Sie jedem Entwickler Zugriff auf Ihre Produktionsumgebung gewähren? Ich denke, es ist besser, nur eine "Master-Konfiguration" zu versionieren und sie in bestimmten Umgebungen zu überschreiben.
Christophe Weis

19

Versioniere diese Datei nicht. Version einer Vorlage oder so.


2
Ich benutze diesen Ansatz, ich habe nur eine main.php.tmpl und wenn ich eine neue Kopie auschecke, kopiere sie einfach nach main, php. Ich füge die Datei main.php zur Ignorierliste hinzu, um ein versehentliches Festschreiben zu vermeiden.
Levhita

10

Mein Team führt für jede Umgebung separate Versionen der Konfigurationsdateien (web.config.dev, web.config.test, web.config.prod). Unsere Bereitstellungsskripte kopieren die richtige Version und benennen sie in web.config um. Auf diese Weise haben wir die volle Versionskontrolle der Konfigurationsdateien für jede Umgebung, können problemlos einen Diff durchführen usw.


6

Derzeit habe ich die Konfigurationsdatei "Vorlage" mit einer hinzugefügten Erweiterung, zum Beispiel:

web.config.rename

Ich kann jedoch ein Problem mit dieser Methode feststellen, wenn sich kritische Änderungen geändert haben.


6

+1 auf dem Vorlagenansatz.

Da diese Frage jedoch mit dem Tag Git versehen ist, fällt mir die verteilte Alternative ein, bei der Anpassungen in einem privaten Testzweig vorgenommen werden:

A---B---C---D---           <- mainline (public)
     \       \
      B'------D'---        <- testing (private)

In diesem Schema enthält die Hauptzeile eine generische "Vorlagen" -Konfigurationsdatei, für deren Funktion nur minimale Anpassungen erforderlich sind.

Jetzt können Entwickler / Tester die Konfigurationsdatei nach Herzenslust anpassen und diese Änderungen nur lokal in einem privaten Testzweig festschreiben (z. B. B '= B + Anpassungen). Jedes Mal, wenn die Hauptlinie voranschreitet, wird sie mühelos zu Tests zusammengeführt, was zu Zusammenführungs-Commits wie D 'führt (= D + zusammengeführte Version der Anpassungen von B).

Dieses Schema leuchtet wirklich, wenn die Konfigurationsdatei "Vorlage" aktualisiert wird: Die Änderungen von beiden Seiten werden zusammengeführt und führen höchstwahrscheinlich zu Konflikten (oder Testfehlern), wenn sie nicht kompatibel sind!


Wenn die Entwickler-Tester jedoch in die Hauptzeile pushen, werden auch ihre Änderungen an der Vorlagendatei übernommen. Nein?
Nick Zalutskiy

Solange es keine Lösung für Nicks Kommentar gibt, wird dies nach meinem Dafürhalten nicht funktionieren. Oder erklären Sie vielleicht, welches Flussmodell Sie verwenden, um das Problem zu lösen.
Alexander Bird

Ich bin mit dem Vorlagenansatz einverstanden, wenn alle erforderlichen Anpassungen zur Erstellungszeit vorgenommen werden. Allerdings zum Thema Verzweigung ... Was wäre, wenn es mehrere Vorlagen (Entwickler, Test usw.) gäbe und Entwickler Änderungen einfach aus ihren Commits auslassen würden? Nicht kinderleicht, könnte aber kooperativ arbeiten.
NickSuperb

5

Die Lösung, die wir verwenden, besteht darin, nur die einzige Konfigurationsdatei (web.config / app.config) zu haben. Wir fügen der Datei jedoch einen speziellen Abschnitt hinzu, der Einstellungen für alle Umgebungen enthält.

Es gibt einen Abschnitt LOCAL, DEV, QA, PRODUCTION , der jeweils die für diese Umgebung relevanten Konfigurationsschlüssel in unseren Konfigurationsdateien enthält.

Damit dies alles funktioniert, ist eine Assembly mit dem Namen xxx.Environment, auf die in allen unseren Anwendungen (Winforms und Webforms) verwiesen wird, die der Anwendung mitteilt, in welcher Umgebung sie ausgeführt wird.

Die xxx.Environment-Assembly liest eine einzelne Informationszeile aus der machine.config des angegebenen Computers, die angibt , dass sie sich auf DEV, QA usw. befindet. Dieser Eintrag ist auf allen unseren Workstations und Servern vorhanden.

Hoffe das hilft.


1
Dies funktioniert sehr gut, wenn es nur wenige Unterschiede zwischen der Umgebung gibt (dh Verbindungszeichenfolgen)
Eric Labashosky

und vorausgesetzt, es gibt nicht Hunderte von Entwicklern, die alle ihre benutzerdefinierten Einstellungen dort ablegen (es würde immer noch funktionieren, aber sehr umständlich sein)
Alexander Bird

5

Ich habe immer alle Versionen der Konfigurationsdateien in der Quellcodeverwaltung im selben Ordner wie die Datei web.config gespeichert.

Beispielsweise

web.config
web.qa.config
web.staging.config
web.production.config

Ich bevorzuge diese Namenskonvention (im Gegensatz zu web.config.production oder Production.web.config), weil

  • Es hält die Dateien zusammen, wenn Sie nach Dateinamen sortieren
  • Es hält die Dateien zusammen, wenn Sie nach Dateierweiterung sortieren
  • Wenn die Datei versehentlich in die Produktion verschoben wird, können Sie den Inhalt nicht über http sehen, da IIS verhindert, dass * .config-Dateien bereitgestellt werden

Die Standardkonfigurationsdatei sollte so konfiguriert sein, dass Sie die Anwendung lokal auf Ihrem eigenen Computer ausführen können.

Am wichtigsten ist, dass diese Dateien in jeder Hinsicht nahezu 100% identisch sind, auch bei der Formatierung. Sie sollten in einer Version keine Tabulatoren und in einer anderen keine Leerzeichen zum Einrücken verwenden. Sie sollten in der Lage sein, ein Diff-Tool für die Dateien auszuführen, um genau zu sehen, was zwischen ihnen unterschiedlich ist. Ich bevorzuge WinMerge, um die Dateien zu unterscheiden.

Wenn Ihr Erstellungsprozess die Binärdateien erstellt, sollte es eine Aufgabe geben, die die web.config mit der für diese Umgebung geeigneten Konfigurationsdatei überschreibt. Wenn die Dateien komprimiert sind, sollten die nicht relevanten Dateien aus diesem Build gelöscht werden.


4

Ich habe die Vorlage bereits verwendet, dh web.dev.config, web.prod.config usw., bevorzuge jetzt jedoch die Technik zum Überschreiben von Dateien. Die Datei web.config enthält die meisten Einstellungen, eine externe Datei enthält jedoch umgebungsspezifische Werte, z. B. Datenbankverbindungen. Gute Erklärung auf Paul Wilsons Blog .

Ich denke, dies reduziert die Menge an Duplikaten zwischen den Konfigurationsdateien, die beim Hinzufügen neuer Werte / Attribute Schmerzen verursachen können.


3

@Grant ist richtig.

Ich bin in einem Team mit fast 100 anderen Entwicklern und unsere Konfigurationsdateien werden nicht in die Quellcodeverwaltung eingecheckt. Wir haben Versionen der Dateien im Repository, die bei jedem Auschecken abgerufen werden, sich aber nicht ändern.

Für uns hat es ganz gut geklappt.


2

Ich kontrolliere die Version, aber schiebe sie niemals auf die anderen Server. Wenn der Produktionsserver eine Änderung erfordert, nehme ich diese Änderung direkt an der Konfigurationsdatei vor.

Es mag nicht schön sein, aber es funktioniert gut.


2

Die eingecheckte Plain-Vanilla-Version von app / web.config sollte generisch genug sein, um auf allen Entwicklercomputern zu funktionieren, und über neue Einstellungsänderungen usw. auf dem Laufenden gehalten werden. Wenn Sie bestimmte Einstellungen für dev benötigen / test / Production-Einstellungen, checken Sie separate Dateien mit diesen Einstellungen ein, wie GateKiller angegeben hat, mit einer Art Namenskonvention, obwohl ich normalerweise mit "web.prod.config" gehe, um die Dateierweiterung nicht zu ändern.


2

Wir verwenden eine Vorlagenkonfigurationsdatei, die zur Versionskontrolle eingecheckt wird, und dann einen Schritt in unserem automatisierten Build, um bestimmte Einträge in der Vorlagendatei durch umgebungsspezifische Einstellungen zu ersetzen. Die umgebungsspezifischen Einstellungen werden in einer separaten XML-Datei gespeichert, die ebenfalls der Versionskontrolle unterliegt.

Wir verwenden MSBuild in unserem automatisierten Build, daher verwenden wir die XmlUpdate-Aufgabe von MSBuild Community Tasks , um die Werte zu aktualisieren.


2

Ich habe lange Zeit genau das getan, was bcwood getan hat. Ich halte Kopien von web.dev.config, web.test.config, web.prod.config usw. unter Quellcodeverwaltung und benenne sie dann automatisch um, wenn es in verschiedenen Umgebungen bereitgestellt wird. Sie erhalten eine gewisse Redundanz zwischen den Dateien (insbesondere mit all den asp.net-Inhalten), aber im Allgemeinen funktioniert es sehr gut. Sie müssen auch sicherstellen, dass sich alle Mitglieder des Teams daran erinnern, alle Dateien zu aktualisieren , wenn sie Änderungen vornehmen.

Übrigens möchte ich ".config" am Ende als Erweiterung behalten, damit die Dateizuordnungen nicht unterbrochen werden.

In Bezug auf lokale Entwicklerversionen der Konfigurationsdatei versuche ich immer mein Bestes, um die Benutzer zu ermutigen, dieselben lokalen Einstellungen so weit wie möglich zu verwenden, sodass keine eigene Version erforderlich ist. Es funktioniert nicht immer für alle. In diesem Fall ersetzen die Leute es normalerweise nur vor Ort vor Ort und gehen von dort aus. Es ist nicht zu schmerzhaft oder so.


1

In unserem Projekt haben wir die Konfiguration in Dateien mit einem Präfix gespeichert, dann zieht unser Build-System die entsprechende Konfiguration basierend auf dem Hostnamen des aktuellen Systems. Dies funktioniert gut für uns in einem relativ kleinen Team, sodass wir Konfigurationsänderungen auf die Dateien anderer Personen anwenden können, wenn wir ein neues Konfigurationselement hinzufügen. Offensichtlich lässt sich dies definitiv nicht auf Open Source-Projekte mit einer unbegrenzten Anzahl von Entwicklern skalieren.


1

Wir haben hier zwei Probleme.

  • Zunächst müssen wir die Konfigurationsdatei steuern, die mit der Software geliefert wird.

    Für Entwickler ist es einfach, eine unerwünschte Änderung an der Master-Konfigurationsdatei einzuchecken, wenn sie dieselbe Datei in der Entwicklungsumgebung verwenden.

    Wenn Sie andererseits eine separate Konfigurationsdatei haben, die vom Installationsprogramm bereitgestellt wird, können Sie leicht vergessen, eine neue Einstellung hinzuzufügen oder die darin enthaltenen Kommentare nicht mehr mit den Kommentaren in der Entwicklung synchronisieren zu lassen Datei konfigurieren.

  • Dann haben wir das Problem, dass Entwickler ihre Kopie der Konfigurationsdatei auf dem neuesten Stand halten müssen, wenn andere Entwickler neue Konfigurationseinstellungen hinzufügen. Einige Einstellungen wie Datenbankverbindungszeichenfolgen sind jedoch für jeden Entwickler unterschiedlich.

  • Es gibt ein drittes Problem, das die Frage / Antwort nicht abdeckt. Wie können Sie die Änderungen, die ein Kunde an Ihrer Konfigurationsdatei vorgenommen hat, zusammenführen, wenn Sie eine neue Version Ihrer Software installieren?

Ich habe noch keine guten Lösungen gefunden, die in allen Fällen gut funktionieren, aber ich habe einige Teillösungen gesehen (die je nach Bedarf in verschiedenen Kombinationen kombiniert werden können), die das Problem erheblich reduzieren.

  • Reduzieren Sie zunächst die Anzahl der Konfigurationselemente in Ihrer Hauptkonfigurationsdatei.

    Wenn Sie nicht zulassen müssen, dass Ihre Kunden Ihre Zuordnungen ändern, verwenden Sie Fluent NHibernate (oder auf andere Weise), um die Konfiguration in Code zu verschieben.

    Ebenso für die Einrichtung der Abhängigkeitsinjektion.

  • Teilen Sie die Konfigurationsdatei nach Möglichkeit auf, z. B. verwenden Sie eine separate Datei, um die Log4Net-Protokolle zu konfigurieren.

  • Wiederholen Sie keine Elemente zwischen vielen Konfigurationsdateien. Wenn Sie beispielsweise 4 Webanwendungen auf demselben Computer installiert haben, verfügen Sie über eine Gesamtkonfigurationsdatei, auf die die Datei web.config in jeder Anwendung verweist.

    (Verwenden Sie standardmäßig einen relativen Pfad, daher muss die Datei web.config nur selten geändert werden.)

  • Verarbeiten Sie die Entwicklungskonfigurationsdatei, um die Versandkonfigurationsdatei zu erhalten.

    Dies kann durch Standardwerte in den XML-Kommentaren erfolgen, die dann in der Konfigurationsdatei festgelegt werden, wenn ein Build abgeschlossen ist. Oder Abschnitte haben, die im Rahmen der Erstellung des Installationsprogramms gelöscht werden.

  • Anstatt nur eine Datenbankverbindungszeichenfolge zu haben, sollten Sie eine pro Entwickler verwenden.

    Suchen Sie beispielsweise zuerst zur Laufzeit in der Konfigurationsdatei nach "database_ianr" (wobei ianr mein Benutzername oder Computername ist). Wenn es nicht gefunden wird, suchen Sie nach "database".

    Mit einem zweiten Level "zB -oracle oder -sqlserver" können Entwickler schneller auf beide Datenbanksysteme zugreifen.

    Dies kann natürlich auch für jeden anderen Konfigurationswert erfolgen.

    Dann können alle Werte, die mit "_userName" enden, vor dem Versand der Konfigurationsdatei entfernt werden.

Am Ende sind Sie jedoch ein "Eigentümer der Konfigurationsdatei", der die Verantwortung für die Verwaltung der Konfigurationsdatei (en) wie oben oder auf andere Weise übernimmt. Er / Sie sollte außerdem vor jeder Sendung einen Unterschied in der Konfigurationsdatei für Kundenbeläge vornehmen.

Sie können die Notwendigkeit einer fürsorglichen Person nicht so kurz vor dem Problem beseitigen.


1

Ich glaube nicht, dass es eine einzige Lösung gibt, die in allen Fällen funktioniert, da dies von der Empfindlichkeit der Daten in den Konfigurationsdateien oder der von Ihnen verwendeten Programmiersprache und so vielen anderen Faktoren abhängen kann. Ich denke jedoch, dass es wichtig ist, die Konfigurationsdateien für alle Umgebungen unter Quellcodeverwaltung zu halten, damit Sie immer wissen, wann sie geändert wurden und von wem und was noch wichtiger ist, sie wiederherstellen können, wenn etwas schief geht. Und sie werden.

Also hier ist, wie ich es mache. Dies ist normalerweise für NodeJS-Projekte, aber ich denke, es funktioniert auch für andere Frameworks und Sprachen.

Ich erstelle ein configsVerzeichnis im Stammverzeichnis des Projekts und speichere unter diesem Verzeichnis mehrere Dateien für alle Umgebungen (und manchmal auch separate Dateien für die Umgebung jedes Entwicklers), die alle in der Quellcodeverwaltung verfolgt werden. Und da ist die eigentliche Datei, die der Code verwendet, benannt configim Stammverzeichnis des Projekts. Dies ist die einzige Datei, die nicht verfolgt wird. So sieht es also aus

root
|
|- config (not tracked)
|
|- configs/ (all tracked)
    |- development
    |- staging
    |- live
    |- James

Wenn jemand das Projekt auscheckt, kopiert er die Konfigurationsdatei, die er in der nicht verfolgten configDatei verwenden möchte, und kann sie nach Belieben bearbeiten. Er ist jedoch auch dafür verantwortlich, diese Änderungen zu kopieren, bevor er sie nach Bedarf in die anderen Umgebungsdateien überträgt.

Auf Servern kann die nicht verfolgte Datei einfach eine Kopie (oder Referenz) der verfolgten Datei sein, die dieser Umgebung entspricht. In JS können Sie einfach 1 Zeile haben, um diese Datei zu benötigen.

Dieser Ablauf mag zunächst etwas kompliziert sein, hat jedoch große Vorteile: 1. Sie müssen sich keine Sorgen machen, dass eine Konfigurationsdatei auf dem Server gelöscht oder geändert wird, ohne über ein Backup zu verfügen. 2. Dasselbe gilt, wenn ein Entwickler eine benutzerdefinierte Konfiguration auf seinem Server hat Maschine und seine Maschine funktionieren aus irgendeinem Grund nicht mehr 3. Vor jeder Bereitstellung können Sie die Konfigurationsdateien für developmentund stagingzum Beispiel unterscheiden und prüfen, ob etwas fehlt oder defekt ist.


0

Wir lassen nur die Produktionskonfigurationsdatei eingecheckt. Es liegt in der Verantwortung des Entwicklers, die Datei zu ändern, wenn sie für die Bereitstellung oder Entwicklung aus dem Quellensafe gezogen wird. Das hat uns in der Vergangenheit verbrannt, also würde ich es nicht vorschlagen.


0

Ich stand vor dem gleichen Problem und fand eine Lösung dafür. Ich habe zuerst alle Dateien zum zentralen Repository hinzugefügt (auch die Entwickler-Dateien).

Wenn ein Entwickler die Dateien aus dem Repository abruft, ist auch die Entwicklerkonfiguration vorhanden. Bei Änderungen an dieser Datei sollte Git diese Änderungen nicht kennen. Auf diese Weise können Änderungen nicht in das Repository übertragen werden, sondern bleiben lokal.

Ich habe dies mit dem Befehl git gelöst : update-index --assume-unchanged. Ich habe eine Bat-Datei erstellt, die im Prebuild der Projekte ausgeführt wird, die eine Datei enthalten, deren Änderungen von Git ignoriert werden sollten. Hier ist der Code, den ich in die Fledermausdatei eingefügt habe:

IF NOT EXIST %2%\.git GOTO NOGIT
set fileName=%1
set fileName=%fileName:\=/%
for /f "useback tokens=*" %%a in ('%fileName%') do set fileName=%%~a
set "gitUpdate=git update-index --assume-unchanged"
set parameter= "%gitUpdate% %fileName%"
echo %parameter% as parameter for git
"C:\Program Files (x86)\Git\bin\sh.exe" --login -i -c %parameter%
echo Make FIleBehaveLikeUnchangedForGit Done.
GOTO END
:NOGIT
echo no git here.
echo %2%
:END

In meinem Prebuild habe ich die Bat-Datei aufgerufen, zum Beispiel:

call "$(ProjectDir)\..\..\MakeFileBehaveLikeUnchangedForGit.bat" "$(ProjectDir)Web.config.developer" "$(SolutionDir)"

Ich habe auf SO eine bat-Datei gefunden, die die richtige Konfigurationsdatei in die Datei web.config / app.config kopiert. Ich nenne diese Bat-Datei auch im Prebuild. Der Code für diese Fledermausdatei lautet:

@echo off
echo Comparing two files: %1 with %2
if not exist %1 goto File1NotFound
if not exist %2 goto File2NotFound
fc %1 %2 
if %ERRORLEVEL%==0 GOTO NoCopy
echo Files are not the same.  Copying %1 over %2
copy %1 %2 /y & goto END
:NoCopy
echo Files are the same.  Did nothing
goto END
:File1NotFound
echo %1 not found.
goto END
:File2NotFound
copy %1 %2 /y
goto END
:END
echo Done.

In meinem Prebuild habe ich die Bat-Datei aufgerufen, zum Beispiel:

call "$(ProjectDir)\..\..\copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config
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.