demarches-simplifiees / demarches-simplifiees.fr

Dématérialiser et simplifier les démarches administratives
https://www.demarches-simplifiees.fr
GNU Affero General Public License v3.0
193 stars 88 forks source link

Amélioration des migrations de données lors de montée de tag (afterparty) #6970

Open mfaure opened 2 years ago

mfaure commented 2 years ago

Objet

L'objet de cette issue est de constituer le point de départ et lieu de discussion pour améliorer les migrations de donnée (et de schéma de base) lors de montée de tag. L'idée est de profiter de "l'expérience" Adullact, où nous avons fait une montée de tag de plus d'un an (!), non sans douleur :)

Actions

/cc @tchak @akarzim @jobygoude @kemenaran @krichtof

Ci-dessous se trouvent les notes du point sur le sujet du mercredi 16 février 2022


DS point migration de données (afterparty) 2022-02-16

Constat

Constat partagé : Dinum / Synbioz

Questions qui se posent :

1. Est-ce que le processus de mise à jour pourrait être mieux documenté ?

Aujourd'hui la base de code ne garantit que des mises à jour d'un tag N à N+1.

Est-ce qu'on pourrait :

2. Est-ce qu'after_party est une bonne manière de décrire les migrations de données ?

after_party n'est plus très actif depuis 2019. À voir si c'est un problème.

Cela dit, after_party n'est qu'un moyen de faire tourner des tâches de migration de données. On peut éventuellement trouver un meilleur moyen technique, mais reste que les tâches de migration de données existeront toujours.

3. Est-ce qu'on pourrait faire en sorte que les migrations N+X soient toujours possible ?

Est-ce qu'on pourrait écrire nos migrations de schéma et de données de sorte qu'il soit toujours possible de faire une mise à jour N+X ?

Pistes

Utiliser ActiveRecord pour les migrations de données

Mastodon fonctionne en mettant les migrations de données dans des migrations ActiveRecord - mais dans un dossier séparé (db/post_deploy au lieu de db/migrate).

Une mise à jour se passe typiquement comme ça :

SKIP_POST_DEPLOY_MIGRATIONS=true bin/rails db:migrate bin/rails server restart bin/rails db:migrate

L'idée est que :

(Implémentation : https://github.com/mastodon/mastodon/blob/c3aef491d66aec743a3a53e934a494f653745b61/config/initializers/0_post_deployment_migrations.rb#L1)

Tester automatiquement l'enchainement des migrations sur la CI

On peut écrire une action de CI qui teste automatiquement que les migrations de schéma et de données depuis un vieux tag de base fonctionnent correctement.

Exemple : https://github.com/mastodon/mastodon/pull/17393/files

Actions

Emplacement de la doc /doc/deploiement.md

Exemple de montées de tag

--- v0.1                                                                            
20190709140415_add_export_queued_to_procedures.rb                                   
20190730153555_recreate_structure.rb                                                
20190805140346_gestionnaire_to_instructeur.rb                                       
20190808144607_link_user_and_instructeur.rb                                         
20190809073736_link_user_and_administrateur.rb                                      
20190819134252_create_groupe_instructeurs.rb                                        
20190819145355_add_groupe_instructeur_column_to_assign_tos.rb                       
20190822143413_add_groupe_instructeur_id_column_to_dossier.rb                       
20190917115911_drop_flipflop_features.rb                                            
20190917120039_remove_carrierwave_columns.rb                                        
20190917120047_remove_devise_columns.rb                                             
20190917120856_remove_unused_columns.rb                                             
20190917151652_make_path_nonnull.rb                                                 
20190920122228_add_indexes_to_dossier.rb                                            
20191014160538_add_routing_criteria_name_column_to_procedure.rb                     
20191023183120_add_default_value_to_routing_criteria_name.rb                        
20191024150452_remove_unique_constraint_on_instructeur_emails.rb                    
20191113142816_instructeurs_remove_email.rb                                         
20191114084643_add_closed_at_to_procedures.rb                                       
20191127113700_add_unpublished_at_to_procedures.rb                                  
20191128081324_add_near_deletion_notice_send_to_dossier.rb                          
20191209141641_remove_administration_id_from_dossier_operation_logs.rb              
20191211101608_create_exports.rb                                                    
20191211113341_create_export_groupe_instructeur_join_table.rb                       
20191211153436_add_en_construction_close_to_expiration_to_dossiers.rb               
20191218103727_add_procedures_path_closed_at_hidden_at_index.rb                     
20200114113700_add_canonical_procedure_id_to_procedures.rb                          
20200130165328_remove_unique_constraint_on_administrateur_emails.rb                 
20200210100938_add_weekly_email_notifications_to_assign_tos.rb                      
20200211170134_administrateurs_remove_email.rb                                      
20200218144724_add_daily_email_notifications_enabled_to_assign_tos.rb               
20200226174444_add_groupe_instructeur_updated_at_to_dossiers.rb                     
20200227100001_remove_email_notifications_enabled_from_assign_tos.rb                
20200304155418_add_diffusable_commercialement_to_etablissements.rb                  
20200319101825_add_en_construction_conservation_extension_to_dossiers.rb            
20200319103836_add_reason_to_deleted_dossiers.rb                                    
20200326120134_add_default_to_en_construction_conservation_extension.rb             
20200331164240_add_termine_close_to_expiration_to_dossiers.rb                       
20200401161821_add_instant_email_message_notifications_to_assign_tos.rb             
20200407135256_add_effectifs_mensuels_to_etablissements.rb                          
20200409075320_add_instant_email_dossier_notifications_to_assign_tos.rb             
20200421174642_rename_effectif_mensuel.rb                                           
20200422090426_add_effectif_annee_anterieure.rb                                     
20200423171759_add_api_entreprise_token_to_procedures.rb                            
20200429191305_add_bilans_bdf_to_etablissements.rb                                  
20200611122406_remove_dossier_procedure_id.rb                                       
20200630140356_create_traitements.rb                                                
20200707082256_remove_instructeur_id_and_add_instructeur_email_to_traitements.rb    
20200707082260_create_procedure_revisions.rb                                        
20200707082261_create_procedure_revision_types_de_champ.rb                          
20200715143010_add_revoked_at_to_avis.rb                                            
20200722135121_add_dossiers_latest_updates_to_dossiers.rb                           
20200819153016_add_enseigne_to_etablissements.rb                                    
20200902103047_remove_type_de_champ_procedure_id.rb                                 
20200930143755_add_allow_instructor_invite_expert.rb                                
20201002124154_create_stats.rb                                                      
20201103165913_add_devise_two_factor_to_administrations.rb                          
20201104163658_create_archive_for_groupe_instructeur.rb                             
20201105131443_rename_administrations_to_super_admins.rb                            
20201110155516_add_relations_to_deleted_dossiers.rb                                 
20201117122923_remove_dossier_operation_log_foreign_key.rb                          
20210107143316_create_experts.rb                                                    
20210107143938_link_user_and_expert.rb                                              
20210112120658_create_experts_procedures.rb                                         
20210113084256_add_experts_procedure_to_avis.rb                                     
20210113150013_add_data_to_champs.rb                                                
20210114224721_add_external_id_to_champs.rb                                         
20210118084107_add_default_skip_content_type_validation_to_piece_justificative.rake 
20210118142539_backfill_experts_procedure_id_on_avis_table.rake                     
--- v1.0                                                                            
20210120121240_add_published_at_to_procedure_revisions.rb                     
20210121134435_add_unique_index_to_experts_procedures.rb                      
20210204180955_add_job_exception_logs.rb                                      
20210307143807_add_claimant_type_to_avis.rb                                   
20210307144755_backfill_claimant_type_on_avis_table.rake                      
20210310170650_remove_invalid_geometries.rake                                 
20210311085419_backfill_claimant_id_for_experts_on_avis_table.rake            
--- v2.0                                                                      
20210311141956_add_tmp_expert_migrated_to_avis.rb                             
20210317094648_add_encrypted_api_particulier_token_to_procedures.rb           
20210318090000_add_service_name_to_active_storage_blobs.active_storage.rb     
20210318090001_create_active_storage_variant_records.active_storage.rb        
20210324081552_backfill_experts_procedure_id_on_avis_table.rake               
--- v3.0                                                                      
20210330112235_add_not_null_service_name_to_active_storage_blobs.rb           
20210331123709_add_cache_key_to_exports.rb                                    
20210331184808_add_revoked_at_to_experts_procedures.rb                        
20210402000000_null_exports_key_to_false.rb                                   
20210402163003_exports_key_not_null.rb                                        
20210407174523_drop_unused_columns.rb                                         
20210409075105_remove_procedure_id_from_assign_tos.rb                         
20210409130604_add_bypass_email_login_token_column_to_instructeur.rb          
20210409131949_populate_bypass_email_login.rake                               
--- v4.0                                                                      
20210412092710_add_data_column_to_france_connect_informations.rb              
20210412093054_fill_missing_date_of_fc.rake                                   
--- v5.0                                                                      
20210416074049_add_experts_require_administrateur_invitation_to_procedures.rb 
20210416160721_add_index_to_exercice_etablissement_id.rb                      
20210419100831_add_deleted_user_email_never_send_to_dossiers.rb               
20210422101149_add_expert_id_to_commentaires.rb                               
20210427112642_rename_content_type_to_to_time_span_type_for_archives.rb       
20210427120000_add_unique_index_to_invites.rb                                 
20210427120001_add_unique_index_to_procedures.rb                              
20210427120002_add_unique_index_to_individuals.rb                             
20210427124500_add_key_to_archives.rb                                         
20210428104228_add_conservation_extension_to_dossiers.rb                      
20210429172327_rename_conservation_extension.rake                             
--- v6.0                                                                      
20210504115445_add_constraints_to_france_connect_informations.rb              
20210506135603_add_default_to_conservation_extension.rb                       
20210512175228_add_time_span_type_to_exports.rb                               
20210513093316_use_jsonb_in_geo_areas_properties.rake                         
--- v7.0                                                                      
20210519092434_add_encrypted_fc_particulier_credentials_to_procedure.rb       
20210525114448_fix_published_revisions.rake                                   
--- v8.0                                                                      
20210604095054_add_declarative_triggered_at_to_dossiers.rb                    
20210630101808_add_parent_id_to_procedure_revision_type_de_champ.rb           
20210630101910_migrate_type_de_champ_parent.rake                              
20210720133539_remove_migration_status_on_filters.rake                        
--- v9.0                                                                           
20210721140812_create_dossier_transfers.rb                                         
20210721162213_create_dossier_transfer_logs.rb                                     
20210722083911_create_bulk_message_mails.rb                                        
20210722133440_add_unique_index_to_champs.rb                                       
20210722133531_add_unique_index_to_deleted_dossiers.rb                             
20210722133553_add_unique_index_to_etablissement.rb                                
20210727172504_add_unique_index_to_bulk_messages_groupe_instructeurs.rb            
20210818083349_add_process_expired_to_traitements.rb                               
20210826161956_add_locale_to_users.rb                                              
20210908162000_add_api_particulier_scopes_to_procedure.rb                          
20210908170019_add_api_particulier_sources_to_procedure.rb                         
20210915083823_add_routing_enabled_to_procedures.rb                                
20210923083416_add_instructeurs_self_management_enabled_to_procedures.rb           
20211001143403_add_identity_updated_at_to_dossier.rb                               
20211005133027_add_value_json_column_to_champ.rb                                   
20211006154552_remove_orphaned_avis.rake                                           
--- v10.0                                                                          
20211006164955_add_manager_to_administrateurs_procedures.rb                        
20211011083203_remove_user_id_not_null_constraint_to_france_connect_information.rb 
20211011102957_add_token_columns_to_france_connect_information.rb                  
20211012100819_add_foreign_key_to_avis_dossier_id.rb                               
20211013131241_add_rebased_at_to_champs.rb                                         
20211020104237_add_champs_etablissement_id_index.rb                                
20211026082232_add_requested_merge_into_column_to_users.rb                         
20211026131800_create_merge_logs.rb                                                
20211104102349_add_lock_version_to_active_storage_blobs.rb                         
20211110093332_set_dossiers_processed_at.rake                                      
--- v11.0                                                                          
20211110095853_add_hide_by_user_at_on_dossiers.rb                                  
20211115112933_add_discarded_at_to_commentaires.rb                                 
20211119112046_add_agent_connect_sub_column_to_instructeurs_table.rb               
20211124111429_add_depose_at_to_dossiers.rb                                        
20211124112843_add_depose_at_to_dossiers.rake                                      
--- v12.0                                                                          
20211124134220_add_migrated_parent_to_types_de_champ.rb                            
20211126080118_add_index_to_deleted_at_to_deleted_dossiers.rb                      
20211126150915_dropfeedbackstable.rb                                               
20211126152402_move_process_expire_to_procedures.rb                                
20211126152402_move_traitement_process_expired_to_procedure.rake                   
--- v13.0                                                                          
20211127133549_create_zones.rb                                                     
20211127143736_add_zone_to_procedures.rb                                           
20211201135804_add_expirants_to_procedure_presentations.rb                         
20211202133139_add_hidden_by_administration_to_dossiers.rb                         
20211214145059_add_attestation_template_id_to_procedure_revisions.rb               
20211259131949_populate_bypass_email_login_again.rake                              
20220112184331_revise_attestation_templates.rake                                   
--- v14.0                                                                          
20220127135056_add_supprimes_recemment_to_procedure_presentations.rb               
akarzim commented 2 years ago

Et ceci c'est cadeau 🎁

find db/migrate/ lib/tasks/deployment -exec basename '{}' \; | sort -n | awk 'BEGIN{ rev = -1 } /^[0-9]{14}_/ { prev=(curr || 0); curr=match($0, /.rb$/); if (prev == 0 && curr != 0) printf "--- v%d.0.0\n", rev += 1; print $0 }'

Le résultat obtenu est le même que dans l'exemple ci-dessus (qui avait été confectionné à la main avec amour)

kemenaran commented 2 years ago

Oh wow, bel example de awk 👌 Je suis partant pour mettre ça dans la doc de déploiement (en attendant d'avoir une meilleure solution technique pour les migrations N+X).

seb-by-ouidou commented 1 year ago

une solution non parfaite mais fonctionnant dans 99% des cas serait de créé des migrations qui appeleraient les after_party. Cela permettrait que la chronologie soit conservée entre les migrations et les after_party, tout en conservant la flexibilité des taches after_party

exemple un fichier /lib/tasks/deployment/20230322172910_populate_zones_with_tchap_hs.rake

namespace :after_party do
  desc 'Deployment task: populate_zones_with_tchap_hs'
  task populate_zones_with_tchap_hs: :environment do
    [...]
    AfterParty::TaskRecord
      .create version: AfterParty::TaskRecorder.new(__FILE__).timestamp
  end
end

et un fichier /db/migrate/20230322172910_populate_zones_with_tchap_hs.rb

class PopulateZonesWithTchapHs < ActiveRecord::Migration[6.1]
  def change
    Rake::Task['after_party:populate_zones_with_tchap_hs'].invoke
  end
end
dzc34 commented 1 year ago

Merci @seb-by-ouidou pour cette proposition.

@tchak @LeSim @colinux @krichtof @mfo un avis ? pour info : @cmayran @Dan33l