Skip to content

Latest commit

 

History

History
221 lines (199 loc) · 8.17 KB

README.rdoc

File metadata and controls

221 lines (199 loc) · 8.17 KB

Moving RubyForge to Redmine

This is the Redmine 0.9.4 release with changes to make it work for RubyForge

Stuff we need to do:

  • Implement a migration script

  • Implement mailing list management

  • Ensure crons work

Migration

I’m thinking about running the migration one project at a time. So the script gets a GForgeGroup, creates a Project, finds the associated GForgeUsers, creates them if necessary, etc. My hope here is that once we’ve completely done one project, the rest will run relatively smoothly, with only some edge cases to account for.

Migration FIXMEs

  • need to upgrade base redmine to latest release - 0.9.6

  • why does [email protected]/password have no issues here /my/page

  • need to populate activity, e.g., /projects/support/activity

Redmine FIXMEs

  • will need to modify Redmine auth to use MD5 since that’s what GForge uses

  • will need to limit => 20 on /projects

General

  • see lib/tasks/migrate_from_gforge.rake

  • To run it: rake db:migrate:reset && rake redmine:migrate_from_gforge REDMINE_LANG=en

  • To migrate just one project: rake redmine:migrate_from_gforge REDMINE_LANG=en GFORGE_GROUP_TO_MIGRATE=rubygems

You can look at both object models in the same Ruby process like this:

$ ./script/console
Loading development environment (Rails 2.3.5)
>> require 'lib/tasks/gforge_models.rb' ; include GForgeMigrate
=> Object
>> GForgeGroup.count
=> 8821
>> Project.count
=> 11

I found it helpful to add this to my ~/.railsrc:

if Dir.getwd == "/Users/tom/github/rubyforge"
  require 'active_record'
  require 'lib/tasks/gforge_models.rb'
  include GForgeMigrate
end

That way I don’t have to type that require every time I get into script/console to troubleshoot a migration failure.

You can set various environment variables to skip parts of the migration: DONT_MIGRATE_DOCUMENTS, DONT_MIGRATE_TRACKERS, DONT_MIGRATE_FORUMS

Some notes on the differences between the GForge and the Redmine object models:

  • GForge stores the user language setting as a foreign key into the supported_languages table. Redmine stores it as a two letter string (e.g., ‘en’) in users.language.

  • The GForge artifact_group_list table gets mapped into rows in the Redmine projects_trackers table (projects HABTM trackers). Redmine trackers are not per project; they are shared for the whole system. The current migration only provisions rows in the projects_trackers table as they are needed - e.g., a project won’t get a “Bug” tracker unless there’s a GForge artifact in a “Bug” GForge artifact_group_list in this project. If there’s a GForge artifact_group_list with an unexpected name (e.g., “Tom’s Issues”) those get mapped into the “Bug” tracker.

  • GForge artifacts have only three statuses (open/closed/deleted) whereas Redmine issues have six possible IssueStatus settings, so I just map them over to the IssueStatus with the same name. GForge artifacts have five priority levels; these map onto Redmine’s five standard IssueCategory values. GForge base64 encodes artifact files; Redmine stores the metadata as an Attachment and stores the data in the RAILS_ROOT/files directory.

  • The GForge forum system handles nested message threads whereas Redmine forum threads are flat (details at www.redmine.org/boards/1/topics/15509). So there’s some lost information there, but, meh.

  • GForge documents had an option to store a URL as a document. I just convert these into a file containing only the URL.

GForge table to Redmine table mapping

artifact                     issues
artifact_category            issue_categories
artifact_file                attachments
artifact_group               project_trackers
artifact_group_list          project_trackers
artifact_history             journals, journal_details
artifact_message             journals
artifact_monitor             watchers
artifact_status              enumerations
doc_data                     documents
doc_groups                   document_categories
filemodule_monitor           
forum                        messages
forum_group_list             boards
forum_monitored_forums       watchers
frs_dlstats_filetotal_agg
frs_file                     attachments
frs_filetype
frs_processor
frs_status
group_cvs_history
group_history
group_plugin
groups                       projects
licenses
mail_group_list
news_bytes
plugins
project_category
project_counts_agg
project_dependencies
project_group_doccat
project_group_forum
project_group_list
project_history
project_messages
project_perm
project_status
project_sums_agg
project_weekly_metric
role
role_setting
trove_agg
trove_cat
trove_group_link
trove_treesums
user_group                   members,member_roles
user_plugin
users                        users,user_preferences

Tables that won’t be migrated

artifact_canned_responses      
activity_log               
activity_log_old           
activity_log_old_old    
api_requests                 
artifact_canned_responses - Couldn't find a Redmine equivalent for this, although it is quite handy
artifact_counts_agg
artifact_extra_field_data
artifact_extra_field_elements
artifact_extra_field_list
artifact_perm - How is this used in GForge... and I don't see an equivalent in Redmine for tracker-specific permissions (?)
artifact_resolution
canned_responses - This table has only 1 record in the RubyForge DB
country_code - These aren't tracked in Redmine
cron_history
db_images - This table has only 1 record in the RubyForge DB
doc_states - We're not migrating 'deleted' documents, and all others are just put in the public
disk_usages                
forum_agg_msg_count
forum_perm - How is this used in GForge?
forum_saved_place
frs_dlstats_file
frs_package - Rolled up into the frs_file => attachments conversion
frs_release - Rolled up into the frs_file => attachments conversion
gem_namespace_ownerships   
massmail_queue
mirrors  
people_job
people_job_category
people_job_inventory
people_job_status
people_skill
people_skill_inventory
people_skill_level
people_skill_year
prdb_dbs - empty in the RubyForge DB
prdb_states - empty in the RubyForge DB
prdb_types - empty in the RubyForge DB
project_assigned_to - part of task system
project_metric
project_metric_tmp1
project_task
project_task_artifact
project_task_external_order
prweb_vhost
rep_group_act_daily
rep_group_act_monthly
rep_group_act_weekly
rep_groups_added_daily
rep_groups_added_monthly
rep_groups_added_weekly
rep_groups_cum_daily
rep_groups_cum_monthly
rep_groups_cum_weekly
rep_time_category
rep_time_tracking
rep_user_act_daily
rep_user_act_monthly
rep_user_act_weekly
rep_users_added_daily
rep_users_added_monthly
rep_users_added_weekly
rep_users_cum_daily
rep_users_cum_monthly
rep_users_cum_weekly
schema_migrations
skills_data
skills_data_types
snippet
snippet_package
snippet_package_item
snippet_package_version
snippet_version
stats_agg_logo_by_day
stats_agg_logo_by_group
stats_agg_pages_by_day
stats_agg_site_by_group
stats_cvs_group
stats_cvs_user
stats_project
stats_project_developers
stats_project_metric
stats_project_months
stats_site
stats_site_months
stats_site_pages_by_day
stats_site_pages_by_month
stats_subd_pages
supported_languages - there's a foreign key to this table from users, and that data is captured in redmine's users.language field
survey_question_types
survey_questions
survey_rating_aggregate
survey_rating_response
survey_responses
surveys
themes
user_bookmarks - only 35 rows in the RubyForge DB... and the settings are RubyForge-specific anyway
user_diary
user_diary_monitor
user_metric - empty in the RubyForge DB
user_metric0 - empty in the RubyForge DB
user_metric_history - empty in the RubyForge DB
user_preferences - only 69 rows in the RubyForge DB... and the settings are RubyForge-specific anyway
user_ratings
user_session
user_type