SkillAgentSearch skills...

RedmineIssueImporter

Configurable PHP CLI tool to import sheets (CSV or others) to Redmine through Redmine´s API. With Custom Fields, and wrong to right values mappings learning.

Install / Use

/learn @juanmf/RedmineIssueImporter
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

RedmineIssueImporter

Please download and use release 1.0.0 currently master version is not tested/guaranteed to work. Use the Command Line and a config yml File to import CVS Sheets as Issues in Redmine. With Custom Fields support. And easily mapping your CSV different/corrupt fields values to the values accepted by Redmine (lists, boolean, date, etc..) fields

The Import process:

  1. Identify the fields in the CVS sheet that match fields in Redmine Issues.

  2. Add connection info to the config file following the example.

  3. Add Custom fields info into the config file, name and id, to allow importer to work properly.

  4. add mapping info, relating fields in sheet with Redmine fields.

  5. Fill Issue default values to use for the issues when the sheet field comes empty or when there is no such field in sheet but redmine forces you to use it.

  6. Run the application from console.

  7. Optionally delete created Issues if mappings should be fixed.

The Update Process:

1 & 2 & 3 & 4 from above Import Process

  1. As oposite to Import, only use default values for fields present in issues sheet. Otherwise you'll override current values in existing issues with their defaults.

  2. Run Application from Comman Line. e.g.

$ php importSheet.php update /tmp/updateDemandas.csv --sheet=updatedemandas --record=demanda

In this example I just used issues Id from /tmp/updateDemandas.csv and set a default value for a new Field (field added after Import). @see Config/Consig.yml

You have three commands:

import --sheet="..." --record="..." [--delimiter="..."] [--fileType="..."] dataFile
update --sheet="..." --record="..." [--delimiter="..."] [--fileType="..."] dataFile
delete [--all] --project="..."

$ php importSheet.php list
..
Available commands:
  delete   Deletes all issues (only if --all) in a project or issued created in last import command run. Does nothing if cant find serielized created issues ids file
  import   Imports issues in a Redmine project, from a data sheet
  update   update issues in a Redmine project, from a data sheet, given that Config/Config.yml denotes the "id" field in sheet

$ php importSheet.php help import
Usage:
 import [--sheet="..."] [--record="..."] [--delimiter="..."] [--fileType="..."] dataFile

Arguments:
 dataFile              absolute file path to the data sheet

Options:
 --sheet               The sheet name config to be used to interpret data in input sheet file.
 --record              The default record name config to be used to interpret data in input sheet file.
 --delimiter           The sheet field delimiter, for CSV.
 --fileType            The default file Format to be used, its case sensitive as the parser class name beggins with this string and ends with 'SheetRecordParser' i.e. 'CsvSheetRecordParser'. (default: "Csv")

$ php importSheet.php help update
Usage:
 update [--sheet="..."] [--record="..."] [--delimiter="..."] [--fileType="..."] dataFile

Arguments:
 dataFile              absolute file path to the data sheet

Options:
 --sheet               The sheet name config to be used to interpret data in input sheet file.
 --record              The default record name config to be used to interpret data in input sheet file.
 --delimiter           The sheet field delimiter, for CSV.
 --fileType            The default file Format to be used, its case sensitive as the parser class name beggins with this string and ends with 'SheetRecordParser' i.e. 'CsvSheetRecordParser'. (default: "Csv")

$ php importSheet.php help delete
Usage:
 delete [--all] [--project="..."]

Options:
 --all                 if Specified, deletes all issues in a project. WARNING! all issues, not just the imported ones.
 --project             This must be set either if --all is set or just last Run Ids need to be deleted. Its the project identifier, the one that appears in the URL. i.e.  <RedmineDomain>/projects/<projectIdentifier>/issues?...

The Config File

Use the following config file format to import sheets into redmine. So far it creates Issues, with custom fields, but it's extensible to add users, etc..

You also have this simpler example Config file I made for a budy in need.

################################################################################
# Run customization
################################################################################
redmine_account:
  # http://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication # show API Key.
  api_key: 'fc..8' # siup
  host: 'http://redmine.myserver.com.ar/'

input_format:
  file_type: 'Csv' # maps to CsvSheetRecordParser
  delimiter: '#'   # field delimiter
  
# false Makes everithing but call save on entities, for tests before hitting API
save_records: true 
################################################################################
# Sheets mapping configuration
################################################################################
on_error:
  behavior: continue # [continue, stop, rollback]
  display_exceptions: false # [true | false]
  
# redmine custom fields settings <objectType> => <customFieldName> => id => <idValue>
custom_fields: 
  issue: 
    sprint: 
      id: 1 # for issues, Intermediario field
    Localidad: 
      id: 19 # for issues, Localidad field
    "Fecha Comprometido": 
      id: 21 # for issues, Fecha Comprometido field
    Telefono: 
      id: 20 # for issues, Telefono field
    Beneficiario: 
      id: 18 # for issues, Beneficiario field
    Intermediario: 
      id: 17 # for issues, Intermediario field

# all sheets that can be importes should be mapped here
sheets: 
  #1st sheet definition
  demandas:  
    # sheet Name, not used unless you add a web form that might use this name.
    name: Planilla de Relevamiento de Demandas Area de Nuevos Medios
    # each sheet could host several record types, here's each definition
    records:
      # recordName use as index to select this config in [Run customization]
      demanda:
        # record Label, not used.
        name: Demanda
        # Redmine Objects/Entities that are related to sheet's data.
        entities:
          # Issue object
          Issue:
            # previously relatd to Doctrien 1.X adapted to Redmine issue types.
            # Not used schema_entity: ~ # si entities[entName] no coincide con el esquema setear este valor
            # object deefault values (in this case Issue) can be [callbackClass, Callbackmethod]
            # these default need not to be in the sheet, but might be mandatory for the API.
            # you could also use defaults for cusotm fields here, just with the name.
            defaults:
              project: A Nuevos Medios, Seguimiento de Demandas
              status: Nueva
              priority: Normal
              assigned_to_id: 92
              author: 'juan'
              due_date: ~
              start_date: [Transform\Defaults\Defaults, startDate]
              tracker: Demanda
              "Fecha Comprometido": '2013-11-01'
              Beneficiario: N/N
              subject: 'Sin Asunto'
              Intermediario: '-----------------'
        
        # These are the fields expected to be present in the CSV or any other sheet like input
        # next definition matched a CSV as follows (showing two records): 
        # [Subject;Description;Sprint] the rest of mandatory values are defined above for "Issue"
        # subject1;Description1;8
        # subject2;Description2;8
        fields:
          # field name
          beneficiario:
            # this key relates this field with Redmine's model described above
            model: {entity: 'Issue', column: 'Beneficiario'}
            # This are the coordinates, where the parser tries to find the 1st occurrence of the field. 
            # Zero based. from the upper-left corner
            coord: {x: 1, y: 0}
            # default value for this field. ovverides other defaults possibly defined above. 
            default: ~ # Si !== ~ pisa al default del schema y al default en [entities]
            # necesary moves to reach next instance of this field, e.i. next record. Normally it'll be just 
            # one step down. (Y+1, X+0). But for values in headers, that appears only once, might be 
            # (Y+0, X+0) so, the same value is used for every record.
            increment: {x: 0, y: 1}  
            # callback that might be needed to transform input data before being persisted.
            transform: ~ # a callback method
            
          subject:
            model: {entity: 'Issue', column: 'subject'} # entity referencia entities[entity] no al schema. Para eso está entities[entity][schema_entity], en caso de que difiera.
            coord: {x: 3, y: 0}
            default: ~ # Si !== ~ pisa al default del schema y al default en [entities]
            increment: {x: 0, y: 1}  # ~ = {x: 0, y: 0} if field is recurrent increment determines the relative loction of the next sibling. ~ means the field is no recurrent, only appears once in a sheet-
            transform: [Transformers\Transformer, asunto] # a callback method
          
          intermediario:
            model: {entity: 'Issue', column: 'Intermediario'} # entity referencia entities[entity] no al schema. Para eso está entities[entity][schema_entity], en caso de que difiera.
            coord: {x: 2, y: 0}
            default: ~ # Si !== ~ pisa al default del schema y al default en [entities]
            increment: {x: 0, y: 1}  # ~ = {x: 0, y: 0} if field is recurrent increment determines the relative loction of the next sibling. ~ means the field is no recurrent, only appears once in a sheet-
            transform: [Transformers\Transformer, intermediario] # a callback method
           
          description:
            model: {entity: 'Issue', column: 'description', glue: '| '} # 
View on GitHub
GitHub Stars33
CategoryEducation
Updated3y ago
Forks9

Languages

PHP

Security Score

60/100

Audited on May 5, 2022

No findings