Cum tratezi fișierele de configurare în controlul sursei?

Să presupunem că aveți o aplicație web tipică și cu o configurație a fișierelor. Fiecare dezvoltator care lucrează la proiect va avea o versiune pentru cutiile sale dev, vor exista versiuni dev, prod și stage. Cum tratezi acest lucru în controlul sursei? Nu verificați deloc acest fișier, verificați-l cu nume diferite sau faceți ceva cu totul altceva?

0
fr hi bn

19 răspunsuri

Nu versiunea acelui fișier. Versiunea unui șablon sau altceva.

0
adăugat
Eu folosesc această abordare, am doar un main.php.tmpl și când am checkout o nouă copie doar copiați-l la main, php. Am adăugat fișierul principal.php în lista de ignorare pentru a evita comiterea accidentală.
adăugat autor levhita, sursa

Versiunea I o controlează, dar nu o împingeți niciodată pe celelalte servere. Dacă serverul de producție necesită o modificare, fac modificarea directă în fișierul de configurare.

Este posibil să nu fie drăguță, dar funcționează bine.

0
adăugat

În prezent, am un fișier de configurare "șablon" cu o extensie adăugată, de exemplu:

web.config.rename

Cu toate acestea, văd o problemă cu această metodă dacă schimbările critice s-au schimbat.

0
adăugat

Echipa mea păstrează versiuni separate ale fișierelor config pentru fiecare mediu (web.config.dev, web.config.test, web.config.prod). Scripturile noastre de implementare copiază versiunea corectă, redenumind-o pe web.config. În acest fel, avem controlul versiunii complete asupra fișierelor de configurare pentru fiecare mediu, poate efectua cu ușurință un diff, etc.

0
adăugat
nu contează pentru setări diferite de mediu, deși dreapta?
adăugat autor shawn, sursa

Versiunea "app / web.config" trebuie să fie suficient de generică pentru a lucra pe toate mașinile de dezvoltare și să fie actualizată cu orice schimbări de setare noi etc. Dacă aveți nevoie de un anumit set de setări pentru dev / test / setări de producție, verificați fișierele separate cu acele setări, după cum a spus GateKiller, cu un fel de convenție de numire, deși eu mă duc de obicei cu "web.prod.config", ca să nu schimb extensia de fișier.

0
adăugat

Ce am făcut în trecut este să aveți un fișier de configurare implicit, care este verificat în controlul sursei. Apoi, fiecare dezvoltator are propriul fișier de configurare de suprascriere, care este exclus din controlul sursei. Aplicația prima încarcă fișierul implicit, iar în cazul în care fișierul de suprascriere este prezent, acesta se încarcă și utilizează orice setări din suprascriere, preferând fișierul implicit.

În general, cu cât fișierul de suprascriere este mai mic cu atât este mai bine, dar poate conține întotdeauna mai multe setări pentru un dezvoltator cu un mediu foarte nestandard.

0
adăugat

Avem două probleme aici.

  • Firstly we have to control the configuration file that is shipped with the software.

    It is all two easy for a developer to check in an unwanted to change to the master config file, if they are using the same file in the devolvement environment.

    On the other side, if you have a separate configuration file that is included by the installer, it is very easy to forget to add a new setting to it, or to let the comments in it get out of sync with the comments in the devolvement configuring file.

  • Then we have the problem that developers have to keep there copy of the configuration file up-to-date as other developers add new configuration settings. However some settings like database connection strings are different for each developer.

  • There is a 3rd problem the question/answers do not cover. How do you merge in the changes a customer have make to your configuration file when you install a new version of your software?

Am văzut încă o soluție bună   care funcționează bine în toate cazurile, totuși   Am văzut câteva soluții parțiale   (care pot fi combinate în diferite   combinații după cum este necesar), care reduce   problema este foarte mult.

  • Firstly reduce the number of configuration items you have in your main configuration file.

    If you don?t have a need to let your customers change your mappings, use Fluent NHibernate (or otherwise) to move the configuration into code.

    Likewise for depency injection setup.

  • Split up the configuration file when possible, e.g. use a separate file to configure what Log4Net logs.

  • Don?t repeat items between lots of configuration files, e.g. if you have 4 web applications that are all installed on the same machine, have a overall configuration file that the web.config file in each application points to.

    (Use a relative path by default, so it is rare to have to change the web.config file)

  • Process the development configuration file to get the shipping configuration file.

    The could be done by have default values in the xml comments that are then set in the configuration file when a build is done. Or having sections that are deleted as part of the process of creating the installer.

  • Instead of just having one database connection strings, have one per developers.

    E.g first look for ?database_ianr? (where ianr is my username or machine name) in the configuration file at run time, if it is not found, then look for ?database?

    Have a 2nd level "e.g. -oracle or -sqlserver" make it quicker for developers to get to both database systems.

    This can of course also be done for any other configuration value.

    Then all values that end in ?_userName? can be striped out before shipping the configuration file.

Cu toate acestea, în cele din urmă ceea ce ești tu e a   ? proprietarul fișierului de configurare? acea   ia responsabilitatea de a gestiona   fișiere de configurare ca mai sus sau   in caz contrar. El / ea ar trebui, de asemenea, să facă a   diff pe acoperirea clientului   fișier de configurare înainte de fiecare   expediere.

Nu puteți elimina necesitatea unei persoane care îngrijește această problemă scurtă.

0
adăugat

Configurația este și ar trebui să o versiune. Ne bazăm fișierele de configurare pe numele de utilizator; atât în ​​UNIX / Mac, cât și în Windows, puteți accesa numele de conectare al utilizatorului și, atâta timp cât acestea sunt unice pentru proiect, sunteți bine. Puteți chiar să înlocuiți acest lucru în mediul înconjurător, însă versiunea trebuie să controleze totul.

Acest lucru vă permite, de asemenea, să examinați configurațiile altor persoane, ceea ce poate ajuta la diagnosticarea problemelor legate de construcție și platformă.

0
adăugat
+1 absolut pentru a sublinia că această configurație ar trebui să fie în continuare versiune
adăugat autor Alexander Bird, sursa
Și dacă numele de utilizator nu este sigur din orice motiv, atunci puteți avea un singur fișier cu o singură linie care să conțină numele fișierului de configurare suprascrie. În acest fel, există puțin foarte puțin (ca în aproximativ 10 caractere sau cam asa ceva) care nu sunt controlate de versiune. Și fișierul README ar putea explica faptul că trebuie să faceți acest fișier.
adăugat autor Alexander Bird, sursa

Pentru mult timp, am făcut exact ceea ce a făcut bcwood-ul. Păstrez copii ale web.dev.config, web.test.config, web.prod.config etc., sub control sursă, iar apoi sistemul meu de construire / implementare le redenumește automat în timp ce se deplasează în diverse medii. Aveți o anumită sumă de redundanță între fișiere (mai ales cu toate lucrurile de pe asp.net), dar, în general, funcționează foarte bine. De asemenea, trebuie să vă asigurați că toată lumea din echipă își amintește să actualizeze toate fișierele atunci când fac o schimbare.

Apropo, îmi place să păstrez ".config" la sfârșit ca extensie, astfel încât asociațiile de fișiere să nu fie rupte.

În ceea ce privește versiunile de dezvoltatori locale ale fișierului de configurare, întotdeauna mă străduiesc să încurajez oamenii să folosească aceleași setări locale cât mai mult posibil, astfel încât să nu fie nevoie să aveți propria versiune. Nu funcționează întotdeauna pentru toată lumea, caz în care oamenii o înlocuiesc, de obicei, local, după cum este necesar, și merg de acolo. Nu e prea dureros sau nimic.

0
adăugat

Tocmai păstrăm fișierul de configurare a producției verificat. Este responsabilitatea dezvoltatorului de a schimba fișierul atunci când îl scoate din sursă în siguranță pentru etapizare sau dezvoltare. Acest lucru ne-a ars în trecut, așa că nu aș sugera-o.

0
adăugat

Folosim un fișier de configurare a șabloanelor care este bifat la controlul versiunii și apoi un pas în construirea noastră automată pentru a înlocui intrările specifice din fișierul șablon cu setările specifice mediului. Setările specifice mediului sunt stocate într-un fișier xml separat, care este, de asemenea, sub controlul versiunii.

Folosim MSBuild în construirea noastră automată, deci folosim sarcina XmlUpdate de la MSBuild Community Tasks pentru a actualiza valori.

0
adăugat

@Grant are dreptate.

Sunt în echipa cu aproape 100 de dezvoltatori, iar fișierele noastre de configurare nu sunt verificate în controlul sursei. Avem versiuni ale fișierelor din depozit care sunt trase cu fiecare verificare, dar ele nu se schimbă.

Sa făcut destul de bine pentru noi.

0
adăugat

Nu cred că există o singură soluție care să funcționeze pentru toate cazurile, deoarece poate depinde de sensibilitatea datelor din fișierele de configurare sau de limbajul de programare pe care îl folosiți și de alți factori. Dar cred că este important să păstrați fișierele de configurare pentru toate mediile aflate sub controlul sursei, astfel încât să puteți ști mereu când a fost schimbată și de către cine și, mai important, să o puteți recupera dacă lucrurile nu merg bine. Și vor.

Deci, iată cum fac asta. Acest lucru este pentru proiecte nodejs de obicei, dar cred că funcționează pentru alte cadre și limbi, de asemenea.

Ceea ce fac este să creez un director configs la rădăcina proiectului și în acest director să păstreze mai multe fișiere pentru toate mediile (și uneori fișiere separate pentru mediul fiecărui dezvoltator), toate urmărite Controlul surselor. Există și fișierul propriu-zis pe care codul îl folosește pe config la rădăcina proiectului. Acesta este singurul fișier care nu este urmărit. Arată așa

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

Când cineva verifică proiectul, copiază fișierul de configurare pe care dorește să îl folosească în fișierul config și nu poate să o edite așa cum dorește, dar este, de asemenea, responsabil să copieze aceste modificări înainte de a se angaja la alte fișiere de mediu, după cum este necesar.

Și pe servere, fișierul netracked poate fi pur și simplu o copie (sau o referință) a fișierului urmărit corespunzător acelui mediu. În JS puteți avea pur și simplu o linie pentru a solicita acest fișier.

Acest flux poate fi un pic mai complicat la început, dar are mari avantaje: 1. Nu trebuie să vă faceți griji că un fișier de configurare a fost șters sau modificat pe server fără a avea o copie de rezervă 2. Același lucru dacă un dezvoltator are unele config personalizate pe mașina lui și mașina lui nu mai lucrează pentru nici un motiv 3. Înainte de orice implementare, puteți difuza fișierele de configurare pentru development și staging de exemplu și vedeți dacă ceva lipsește sau este rupt.

0
adăugat
@Noumenon a actualizat răspunsul pentru a clarifica
adăugat autor Gaafar, sursa

+1 pentru abordarea șablonului.

Dar din moment ce această întrebare are eticheta Git, alternativa distribuită izvoare în minte, în care personalizările sunt păstrate pe o testare privată ramură:

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

În această schemă, linia principală conține o configurație generică, "șablon" fișier care necesită cantitatea minimă de ajustări pentru a deveni funcțională.

Acum, dezvoltatorii / testerii pot optimiza fișierul de configurare în inima lor conținut și comitem aceste modificări numai local pe una privată (de exemplu, B '= personalizări B +). De fiecare dată linia principală avansuri, le combină fără efort în testare, care are ca rezultat îmbinarea comitetelor, cum ar fi D '(= D + versiunea îmbinată a personalizărilor lui B).

Această schemă strălucește cu adevărat când fișierul de configurare "șablon" este actualizat: schimbările de la ambele părți devin fuzionate și sunt extrem de probabil să duceți la conflicte (sau la eșecuri de testare) dacă acestea sunt incompatibile!

0
adăugat
Dar, atunci când dezvoltatorii testeri împinge în linia principală, schimbările lor la fișierul șablon vor fi împinse în, de asemenea. Nu?
adăugat autor Nick Zalutskiy, sursa
Dacă nu există o soluție la comentariul lui Nick, acest lucru nu va funcționa din ceea ce văd. Sau poate explicați ce model de flux utilizați, care ar rezolva problema.
adăugat autor Alexander Bird, sursa
Sunt de acord cu abordarea șablonului, cu toate ajustările necesare la momentul construirii. Cu toate acestea, pe subiectul ramificat ... Ce se întâmplă dacă au existat mai multe șabloane (dev, test, etc.) și dezvoltatorii pur și simplu omit modificările de la comitetele lor. Nu este sigur, dar ar putea colabora.
adăugat autor NickSuperb, sursa

Pe proiectul nostru avem o configurație stocată în fișiere cu un prefix, apoi sistemul nostru de construire trage în configurația corespunzătoare bazată pe numele de gazdă al sistemului curent. Acest lucru funcționează bine pentru noi într-o echipă relativ mică, permițându-ne să aplicăm modificări de configurare în fișierele altor persoane dacă / când adăugăm un nou element de configurare. Evident, acest lucru nu se limitează la proiecte open source cu un număr nelimitat de dezvoltatori.

0
adăugat

Am folosit șablonul înainte, adică web.dev.config, web.prod.config, etc, dar acum preferă tehnica "suprascriere fișier". Fișierul web.config conține majoritatea setărilor, dar un fișier extern conține valori specifice mediului, cum ar fi conexiunile db. O explicație bună despre blogul lui Paul Wilson .

Cred că acest lucru reduce cantitatea de duplicare între fișierele de configurare care pot provoca durere atunci când se adaugă noi valori / atribute.

0
adăugat

Soluția utilizată este să avem doar singurul fișier de configurare (web.config / app.config), dar adăugăm o secțiune specială fișierului care conține setări pentru toate mediile.

Există secțiuni LOCALE, DEV, QA, PRODUCTION , fiecare conținând cheile de configurare relevante pentru acel mediu în fișierul (ele) de configurare.

Ceea ce face ca toate acestea să funcționeze este un ansamblu numit xxx.Environment care face referire în toate aplicațiile noastre (winforms și webforms), care indică aplicației în ce mediu lucrează.

Ansamblul xxx.Environment citește o singură linie de informații de la machine.config a mașinii date care îi spune că este pe DEV, QA etc. Această intrare este prezentă pe toate stațiile de lucru și servere.

Sper că acest lucru vă ajută.

0
adăugat
și presupunând că nu există 100 de dezvoltatori care să-și pună setările personalizate acolo, de asemenea (ar funcționa în continuare, dar ar fi foarte greoaie)
adăugat autor Alexander Bird, sursa
Acest lucru funcționează foarte bine dacă există doar câteva diferențe între mediu (de exemplu, șiruri de conexiune)
adăugat autor Eric Labashosky, sursa

Am păstrat întotdeauna toate versiunile fișierelor de configurare în controlul sursă, în același folder ca și fișierul web.config.

De exemplu

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

Prefer această convenție de denumire (spre deosebire de web.config.production sau production.web.config) deoarece

  • Păstrează fișierele împreună atunci când sortați după numele fișierului
  • păstrează fișierele împreună atunci când sortați după extensia fișierelor
  • Dacă fișierul intră accidental în producție, nu veți putea vedea conținutul peste http deoarece IIS va împiedica difuzarea fișierelor * .config

Fișierul de configurare implicit trebuie să fie configurat astfel încât să puteți rula aplicația local pe mașina proprie.

Cel mai important, aceste fișiere ar trebui să fie aproape 100% identice în fiecare aspect, chiar formatare. Nu trebuie să utilizați filele într-o singură versiune, iar spațiile în alta pentru indentare. Ar trebui să puteți rula un instrument diff împotriva fișierelor pentru a vedea exact ce este diferit între ele. Prefer să folosesc WinMerge pentru difuzarea fișierelor.

Când procesul dvs. de construire creează fișierele binare, ar trebui să existe o sarcină care suprascrie web.config-ul cu fișierul de configurare corespunzător acelui mediu. Dacă fișierele sunt închise, atunci fișierele care nu sunt relevante ar trebui să fie șterse din acea construcție.

0
adăugat

M-am confruntat cu aceeași problemă și am găsit o soluție pentru asta. Am adăugat mai întâi toate fișierele la depozitul central (de asemenea, cele de dezvoltator).

Deci, dacă un dezvoltator preia fișierele din depozit, există și configurarea dezvoltatorului. Când se efectuează o modificare a acestui fișier, Git nu ar trebui să fie conștient de aceste modificări. În acest fel, schimbările nu pot fi împinse / angajate în depozit, ci rămân la nivel local.

Am rezolvat aceasta folosind comanda git: update-index --assume -changed . Am făcut un fișier de bat care este executat în prebuild pentru proiectele care conțin un fișier ale cărui modificări ar trebui ignorate de Git. Iată codul pe care l-am pus în fișierul de lilieci:

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

În prebuild mea aș fi sunat la fișierul de lilieci, de exemplu:

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

Am găsit pe SO un fișier de tip bat care copiază fișierul de configurare corect la web.config / app.config. De asemenea, numesc acest fișier bat în prebuild. Codul pentru acest fișier bat este:

@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.

În prebuild mea aș fi sunat la fișierul de lilieci, de exemplu:

call "$(ProjectDir)\..\..\copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config
0
adăugat