Bagaimana Anda menangani file konfigurasi di kontrol sumber?

97

Katakanlah Anda memiliki aplikasi web biasa dan dengan konfigurasi file. Apa pun. Setiap pengembang yang mengerjakan proyek akan memiliki satu versi untuk dev box mereka, akan ada versi dev, prod dan stage. Bagaimana Anda menangani ini di kendali sumber? Tidak memeriksa file ini sama sekali, memeriksanya dengan nama yang berbeda atau melakukan sesuatu yang mewah sama sekali?

programer mati
sumber

Jawaban:

70

Apa yang saya lakukan di masa lalu adalah memiliki file konfigurasi default yang diperiksa ke kontrol sumber. Kemudian, setiap pengembang memiliki file konfigurasi timpaannya sendiri yang dikecualikan dari kontrol sumber. Aplikasi pertama memuat default, dan kemudian jika file timpa ada, muat itu dan menggunakan pengaturan apa pun dari override dalam preferensi ke file default.

Secara umum, semakin kecil file yang ditimpa, semakin baik, tetapi selalu dapat berisi lebih banyak pengaturan untuk pengembang dengan lingkungan yang sangat tidak standar.

yukondude
sumber
24

Konfigurasi adalah kode, dan Anda harus membuat versinya. Kami mendasarkan file konfigurasi kami pada nama pengguna; di UNIX / Mac dan Windows Anda dapat mengakses nama login pengguna, dan selama ini unik untuk proyek, Anda baik-baik saja. Anda bahkan dapat menimpanya di lingkungan, tetapi Anda harus mengontrol versi semuanya.

Ini juga memungkinkan Anda untuk memeriksa konfigurasi orang lain, yang dapat membantu mendiagnosis masalah build dan platform.

davetron5000
sumber
10
+1 mutlak untuk menekankan bahwa konfigurasi masih harus diversi
Alexander Bird
Dan jika nama pengguna tidak dapat diandalkan karena alasan apa pun, maka Anda dapat memiliki satu file dengan hanya satu baris yang memberi nama file konfigurasi timpa. Dengan cara ini, sangat sedikit (seperti sekitar 10 karakter atau lebih) yang tidak dikontrol versi. Dan file README dapat menjelaskan bahwa Anda perlu membuat file tersebut.
Alexander Bird
Saya selalu berpikir bahwa konfigurasi harus dipisahkan dari kode. Saya telah bekerja di tempat-tempat yang membutuhkan begitu banyak konfigurasi untuk satu repo sehingga Git kewalahan dengan file konfigurasi. Tidak mengatakan bahwa konfigurasi tidak boleh diversi, mereka milik tempat lain seperti manajer artefak. Config bukanlah kode, mereka adalah pengaturan untuk kode.
Thomas
File konfigurasi mungkin berisi informasi sensitif seperti kata sandi yang tidak boleh diversi. Atau apakah Anda ingin memberi setiap pengembang akses ke lingkungan produksi Anda? Saya pikir lebih baik hanya versi "master config" dan menimpanya dalam lingkungan tertentu.
Christophe Weis
19

Jangan versi file itu. Buat versi template atau sesuatu.

Hibah
sumber
2
Saya menggunakan pendekatan ini, saya hanya memiliki main.php.tmpl dan ketika saya melakukan checkout salinan baru cukup salin ke main, php. Saya menambahkan file main.php ke daftar abaikan untuk menghindari melakukannya secara tidak sengaja.
levhita
10

Tim saya menyimpan versi terpisah dari file konfigurasi untuk setiap lingkungan (web.config.dev, web.config.test, web.config.prod). Skrip penerapan kami menyalin versi yang benar, mengganti namanya menjadi web.config. Dengan cara ini, kami memiliki kontrol versi penuh pada file konfigurasi untuk setiap lingkungan, dapat dengan mudah melakukan diff, dll.

Brandon Wood
sumber
6

Saat ini saya memiliki file konfigurasi "template" dengan ekstensi tambahan, misalnya:

web.config.rename

Namun, saya dapat melihat masalah dengan metode ini jika perubahan kritis telah berubah.

GateKiller
sumber
6

+1 pada pendekatan template.

Tetapi karena pertanyaan ini memiliki tag Git, alternatif terdistribusi muncul dalam pikiran, di mana kustomisasi disimpan pada cabang pengujian pribadi:

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

Dalam skema ini, jalur utama berisi file konfigurasi "template" generik yang memerlukan sedikit penyesuaian agar dapat berfungsi.

Sekarang, pengembang / penguji dapat mengubah file konfigurasi ke isi hati mereka, dan hanya melakukan perubahan ini secara lokal pada satu cabang pengujian pribadi (misalnya B '= B + kustomisasi). Setiap kali jalur utama maju, mereka dengan mudah menggabungkannya ke dalam pengujian, yang menghasilkan komit gabungan seperti D '(= D + versi gabungan dari penyesuaian B).

Skema ini benar-benar bersinar ketika file konfigurasi "template" diperbarui: perubahan dari kedua sisi digabungkan, dan sangat mungkin menyebabkan konflik (atau kegagalan uji) jika tidak kompatibel!

Damien Diederen
sumber
Namun saat penguji developer mendorong ke jalur utama, perubahan mereka pada file template juga akan diterapkan. Tidak?
Nick Zalutskiy
Kecuali ada solusi untuk komentar Nick, ini tidak akan berhasil dari apa yang saya lihat. Atau mungkin menjelaskan model aliran apa yang Anda gunakan yang akan menyelesaikan masalah.
Alexander Bird
Saya setuju dengan pendekatan template dengan setiap penyesuaian yang diperlukan yang dibuat pada waktu pembuatan. Namun pada topik percabangan ... Bagaimana jika ada beberapa template (dev, test, dll.) Dan developer mengabaikan perubahan dari commit mereka. Tidak sangat mudah tetapi bisa bekerja sama.
NickSuperb
5

Solusi yang kami gunakan adalah hanya memiliki satu file konfigurasi (web.config / app.config), tetapi kami menambahkan bagian khusus ke file yang berisi pengaturan untuk semua lingkungan.

Ada bagian LOKAL, DEV, QA, PRODUCTION yang masing-masing berisi kunci konfigurasi yang relevan dengan lingkungan tersebut di file konfigurasi kami.

Apa yang membuat ini semua bekerja adalah rakitan bernama xxx.Environment yang direferensikan di semua aplikasi kami (winforms dan webforms) yang memberi tahu aplikasi di lingkungan mana ia beroperasi.

Rakitan xxx.Environment membaca satu baris informasi dari machine.config dari mesin yang diberikan yang memberitahukan bahwa ia ada di DEV, QA, dll. Entri ini ada di semua workstation dan server kami.

Semoga ini membantu.

Jason Stevenson
sumber
1
Ini bekerja sangat baik jika hanya ada sedikit perbedaan antara lingkungan (yaitu string koneksi)
Eric Labashosky
dan dengan asumsi tidak ada 100 pengembang yang semuanya menempatkan pengaturan khusus mereka di sana (ini masih akan berfungsi, tetapi akan sangat rumit)
Alexander Bird
5

Saya selalu menyimpan semua versi file konfigurasi di kontrol sumber, di folder yang sama dengan file web.config.

Sebagai contoh

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

Saya lebih suka konvensi penamaan ini (sebagai lawan web.config.production atau production.web.config) karena

  • Itu membuat file tetap bersama saat Anda mengurutkan berdasarkan nama file
  • Itu menyimpan file bersama saat Anda mengurutkan berdasarkan ekstensi file
  • Jika file secara tidak sengaja didorong ke produksi, Anda tidak akan dapat melihat konten melalui http karena IIS akan mencegah file * .config disajikan

File konfigurasi default harus dikonfigurasi sehingga Anda dapat menjalankan aplikasi secara lokal di komputer Anda sendiri.

Yang terpenting, file-file ini harus hampir 100% identik di setiap aspek, bahkan formatnya. Anda tidak boleh menggunakan tab dalam satu versi dan spasi di versi lain untuk membuat indentasi. Anda harus dapat menjalankan alat diff terhadap file untuk melihat dengan tepat apa yang berbeda di antara mereka. Saya lebih suka menggunakan WinMerge untuk membedakan file.

Saat proses build Anda membuat biner, seharusnya ada tugas yang menimpa web.config dengan file konfigurasi yang sesuai untuk lingkungan tersebut. Jika file dizip, maka file yang tidak relevan harus dihapus dari build itu.

JackAce
sumber
4

Saya telah menggunakan template sebelumnya, yaitu web.dev.config, web.prod.config, dll, tetapi sekarang lebih memilih teknik 'timpa file'. File web.config berisi sebagian besar pengaturan, tetapi file eksternal berisi nilai spesifik lingkungan seperti koneksi db. Penjelasan bagus di blog Paul Wilson .

Saya pikir ini mengurangi jumlah duplikasi antara file konfigurasi yang dapat menyebabkan rasa sakit saat menambahkan nilai / atribut baru.

Andy Whitfield
sumber
3

@ Grant benar.

Saya berada dalam tim dengan hampir 100 pengembang lain, dan file konfigurasi kami tidak diperiksa ke kontrol sumber. Kami memiliki versi file dalam repositori yang ditarik dengan setiap check out tetapi tidak berubah.

Ini berhasil dengan baik bagi kami.

Tom
sumber
2

Saya mengontrol versi itu, tetapi tidak pernah mendorongnya ke server lain. Jika server produksi memerlukan perubahan, saya membuat perubahan itu langsung ke file konfigurasi.

Ini mungkin tidak cantik, tetapi berfungsi dengan baik.

EndangeredMassa
sumber
2

Versi aplikasi / web.config biasa-biasa saja yang check-in seharusnya cukup umum untuk bekerja pada semua mesin pengembang, dan selalu diperbarui dengan perubahan pengaturan baru, dll. Jika Anda memerlukan set pengaturan khusus untuk dev / test / production settings, periksa di file terpisah dengan pengaturan tersebut, seperti yang dinyatakan GateKiller, dengan semacam konvensi penamaan, meskipun saya biasanya menggunakan "web.prod.config", agar tidak mengubah ekstensi file.

Greg Hurlman
sumber
2

Kami menggunakan file konfigurasi template yang diperiksa ke kontrol versi dan kemudian langkah dalam build otomatis kami untuk mengganti entri tertentu di file template dengan pengaturan khusus lingkungan. Pengaturan khusus lingkungan disimpan dalam file XML terpisah yang juga di bawah kontrol versi.

Kami menggunakan MSBuild dalam pembuatan otomatis kami, jadi kami menggunakan tugas XmlUpdate dari Tugas Komunitas MSBuild untuk memperbarui nilai.

Sean Carpenter
sumber
2

Untuk waktu yang lama, saya telah melakukan apa yang telah dilakukan bcwood. Saya menyimpan salinan web.dev.config, web.test.config, web.prod.config, dll. Di bawah kendali sumber, dan kemudian sistem build / deploy saya mengganti namanya secara otomatis saat diterapkan ke berbagai lingkungan. Anda mendapatkan sejumlah redundansi di antara file (terutama dengan semua hal asp.net di sana), tetapi umumnya berfungsi dengan sangat baik. Anda juga harus memastikan bahwa semua orang di tim ingat untuk memperbarui semuanya file saat mereka membuat perubahan.

Omong-omong, saya ingin menyimpan ".config" di akhir sebagai ekstensi agar asosiasi file tidak rusak.

Sejauh versi pengembang lokal dari file konfigurasi, saya selalu berusaha sebaik mungkin untuk mendorong orang menggunakan pengaturan lokal yang sama sebanyak mungkin sehingga tidak perlu memiliki versi Anda sendiri. Itu tidak selalu berhasil untuk semua orang, dalam hal ini orang biasanya hanya menggantinya secara lokal sesuai kebutuhan dan pergi dari sana. Itu tidak terlalu menyakitkan atau apapun.

jeremcc
sumber
1

Pada proyek kami, kami memiliki konfigurasi yang disimpan dalam file dengan awalan, lalu sistem build kami menarik konfigurasi yang sesuai berdasarkan nama host sistem saat ini. Ini berfungsi dengan baik bagi kami di tim yang relatif kecil, memungkinkan kami menerapkan perubahan konfigurasi ke file orang lain jika / ketika kami menambahkan item konfigurasi baru. Jelas ini jelas tidak berskala untuk proyek open source dengan jumlah pengembang yang tidak terbatas.

Rob Oxspring
sumber
1

Kami memiliki dua masalah di sini.

  • Pertama kita harus mengontrol file konfigurasi yang dikirimkan bersama perangkat lunak.

    Ini adalah dua hal yang mudah bagi pengembang untuk memeriksa perubahan yang tidak diinginkan ke file konfigurasi utama, jika mereka menggunakan file yang sama di lingkungan devolvement.

    Di sisi lain, jika Anda memiliki file konfigurasi terpisah yang disertakan oleh penginstal, sangat mudah untuk lupa untuk menambahkan pengaturan baru ke dalamnya, atau membiarkan komentar di dalamnya tidak sinkron dengan komentar di devolvement mengkonfigurasi file.

  • Kemudian kami memiliki masalah bahwa pengembang harus terus memperbarui salinan file konfigurasi saat pengembang lain menambahkan pengaturan konfigurasi baru. Namun beberapa pengaturan seperti string koneksi database berbeda untuk setiap pengembang.

  • Ada masalah ketiga yang tidak dicakup oleh pertanyaan / jawaban. Bagaimana Anda menggabungkan perubahan yang dibuat pelanggan pada file konfigurasi Anda ketika Anda menginstal versi baru perangkat lunak Anda?

Saya belum melihat solusi bagus yang berfungsi dengan baik di semua kasus, namun saya telah melihat beberapa solusi parsial (yang dapat digabungkan dalam kombinasi berbeda sesuai kebutuhan) yang banyak mengurangi masalah.

  • Pertama, kurangi jumlah item konfigurasi yang Anda miliki di file konfigurasi utama Anda.

    Jika Anda tidak perlu membiarkan pelanggan Anda mengubah pemetaan, gunakan Fluent NHibernate (atau sebaliknya) untuk memindahkan konfigurasi ke dalam kode.

    Begitu juga untuk penyetelan injeksi depensi.

  • Pisahkan file konfigurasi jika memungkinkan, mis. Gunakan file terpisah untuk mengkonfigurasi log Log4Net apa.

  • Jangan mengulang item di antara banyak file konfigurasi, misalnya jika Anda memiliki 4 aplikasi web yang semuanya diinstal pada mesin yang sama, miliki file konfigurasi keseluruhan yang ditunjuk oleh file web.config di setiap aplikasi.

    (Gunakan jalur relatif secara default, jadi sangat jarang harus mengubah file web.config)

  • Proses file konfigurasi pengembangan untuk mendapatkan file konfigurasi pengiriman.

    Dapat dilakukan dengan memiliki nilai default di komentar Xml yang kemudian disetel dalam file konfigurasi saat build selesai. Atau memiliki bagian yang dihapus sebagai bagian dari proses pembuatan penginstal.

  • Alih-alih hanya memiliki satu string koneksi database, miliki satu string untuk setiap pengembang.

    Misalnya, cari dulu "database_ianr" (di mana ianr adalah nama pengguna atau nama mesin saya) di file konfigurasi pada saat dijalankan, jika tidak ditemukan, cari "database"

    Memiliki level kedua "eg -oracle or -sqlserver" membuatnya lebih cepat bagi pengembang untuk mengakses kedua sistem database.

    Ini tentu saja juga dapat dilakukan untuk nilai konfigurasi lainnya.

    Kemudian semua nilai yang diakhiri dengan "_userName" dapat dihapus sebelum mengirimkan file konfigurasi.

Namun pada akhirnya Anda adalah “pemilik file konfigurasi” yang bertanggung jawab untuk mengelola file konfigurasi seperti di atas atau sebaliknya. Dia / Dia juga harus melakukan perbedaan pada file konfigurasi tampilan pelanggan sebelum setiap pengiriman.

Anda tidak dapat menghilangkan kebutuhan akan orang yang penuh perhatian pada beberapa masalah singkat ini.

Ian Ringrose
sumber
1

Saya tidak berpikir ada satu solusi yang berfungsi untuk semua kasus karena mungkin bergantung pada sensitivitas data dalam file konfigurasi, atau bahasa pemrograman yang Anda gunakan, dan banyak faktor lainnya. Tetapi menurut saya penting untuk menyimpan file konfigurasi untuk semua lingkungan di bawah kendali sumber, sehingga Anda selalu dapat mengetahui kapan itu diubah dan oleh siapa, dan yang lebih penting, dapat memulihkannya jika terjadi kesalahan. Dan mereka akan melakukannya.

Jadi, inilah cara saya melakukannya. Ini untuk proyek nodejs biasanya tetapi saya pikir ini berfungsi untuk kerangka kerja dan bahasa lain juga.

Apa yang saya lakukan adalah membuat configsdirektori di root proyek, dan di bawah direktori itu simpan banyak file untuk semua lingkungan (dan beberapa kali file terpisah untuk setiap lingkungan pengembang juga) yang semuanya dilacak dalam kontrol sumber. Dan ada file sebenarnya yang digunakan kode yang dinamai configdi root proyek. Ini adalah satu-satunya file yang tidak terlacak. Jadi ini terlihat seperti ini

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

Ketika seseorang memeriksa proyek, dia menyalin file konfigurasi yang ingin dia gunakan di untracked config file yang tidak dan dia bebas untuk mengeditnya sesuai keinginannya, tetapi juga bertanggung jawab untuk menyalin perubahan ini sebelum dia berkomitmen ke file lingkungan lain sesuai kebutuhan.

Dan di server, file yang tidak terlacak dapat dengan mudah menjadi salinan (atau referensi) dari file yang dilacak yang sesuai dengan lingkungan itu. Di JS Anda cukup memiliki 1 baris untuk meminta file itu.

Alur ini mungkin sedikit rumit pada awalnya tetapi memiliki keuntungan besar: 1. Anda tidak perlu khawatir file konfigurasi akan terhapus atau dimodifikasi di server tanpa memiliki cadangan 2. Hal yang sama jika pengembang memiliki beberapa konfigurasi khusus di dalamnya mesin dan mesinnya berhenti bekerja karena alasan apa pun 3. Sebelum penerapan apa pun, Anda dapat membedakan file konfigurasi developmentdan stagingmisalnya dan melihat apakah ada yang hilang atau rusak.

gafi
sumber
0

Kami hanya membiarkan file konfigurasi produksi diperiksa. Merupakan tanggung jawab pengembang untuk mengubah file ketika mereka mengeluarkannya dari sumber yang aman untuk pementasan atau pengembangan. Ini telah membakar kita di masa lalu jadi saya tidak akan menyarankannya.

Ryan
sumber
0

Saya menghadapi masalah yang sama dan saya menemukan solusi untuk itu. Saya pertama kali menambahkan semua file ke repositori pusat (juga yang pengembang).

Jadi, jika pengembang mengambil file dari repositori, konfigurasi pengembang juga ada di sana. Saat mengubah dibuat ke file ini, Git seharusnya tidak menyadari perubahan ini. Dengan cara itu perubahan tidak dapat didorong / dikomit ke repositori tetapi tetap secara lokal.

Saya diselesaikan ini dengan menggunakan perintah git: update-index --assume-unchanged. Saya membuat file bat yang dieksekusi dalam prebuild proyek yang berisi file yang perubahannya harus diabaikan oleh Git. Berikut kode yang saya masukkan ke dalam file bat:

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

Dalam prebuild saya, saya akan melakukan panggilan ke file bat, misalnya:

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

Saya menemukan di SO sebuah file bat yang menyalin file konfigurasi yang benar ke web.config / app.config. Saya juga menyebut file bat ini di prebuild. Kode untuk file bat ini adalah:

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

Dalam prebuild saya, saya akan melakukan panggilan ke file bat, misalnya:

call "$(ProjectDir)\..\..\copyifnewer.bat" "$(ProjectDir)web.config.$(ConfigurationName)" "$(ProjectDir)web.config
Benny Emmers
sumber