Last active
December 30, 2015 03:59
-
-
Save bronumski/7773030 to your computer and use it in GitHub Desktop.
FSharp script to import into YouTrack from a CSV file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Constants = | |
[<Literal>] | |
let ImportDataFileUrl = "Data.csv" | |
let YouTrackUrl = "http://LocalHost:8082" | |
let YouTrackAdminUserName = "root" | |
let YouTrackAdminPassword = "password" | |
let YouTrackProjectID = "PROJ" | |
#r "FSharp.Data.1.1.10/lib/net40/FSharp.Data.dll" | |
#r "RestSharp.104.4.0/lib/net4/RestSharp.dll" | |
open System.Xml.Serialization | |
open FSharp.Data | |
open RestSharp | |
type ImportIssue = CsvProvider<Constants.ImportDataFileUrl> | |
let getCurrentTicks(importedIssue : ImportIssue.Row) = | |
System.DateTime.Now.Ticks.ToString() | |
let mappings = | |
[ //YOUTRACK FIELD NAME TYPE CARDINALITY REQUIRED DESCRIPTION | |
"numberInProject", fun (issue : ImportIssue.Row) -> issue.Number.ToString(); // long single YES Issue number in project. Should be unique | |
"summary", fun issue -> issue.Name; // string single YES Issue summary | |
"description", fun issue -> issue.Description; // string single NO Full issue description | |
"created", getCurrentTicks; // UNIX Epoch timestamp single YES Issue creation time | |
"updated", fun issue -> null; // UNIX Epoch timestamp single NO Last issue update time | |
"updaterName", fun issue -> null; // string single NO Login name of last issue updater | |
"resolved", fun issue -> null; // UNIX Epoch timestamp single NO Issue resolve time | |
"reporterName", fun issue -> "root"; // string single NO Login name of issue reporter | |
"voterName", fun issue -> null; // string multi NO Login names of users who voted for the issue. | |
"watcherName", fun issue -> null; // string multi NO Login names of users who enabled watching issue changes. | |
"permittedGroup", fun issue -> null; // string single NO Name of group that has an access to the issue. See GET Groups | |
] | |
type Field(fieldName, fieldValue) = | |
[<XmlAttribute("name")>] member val FieldName = fieldName with get, set | |
[<XmlElement("value")>] member val FieldValue = fieldValue with get, set | |
public new() = Field("","") | |
type Issue(fields: Field[]) = | |
[<XmlElement "field">] member val Fields = fields with get, set | |
public new() = Issue([||]) | |
[<XmlRoot("issues")>] | |
type YoutrackIssues(issues: Issue[]) = | |
[<XmlElement("issue")>] member val Issues = issues with get, set | |
public new() = YoutrackIssues([||]) | |
let mapImportedIssue (issueToMap : ImportIssue.Row) fieldMappings = | |
let myMappedFields = fieldMappings |> Seq.choose (function | name, value when value(issueToMap) <> null -> Some(Field(name, value(issueToMap))) | _ -> None) | |
new Issue(Seq.toArray(myMappedFields)) | |
let importedIssues = ImportIssue.Load Constants.ImportDataFileUrl | |
let mapImportedIssues (issuesToMap : ImportIssue.Row seq) fieldMappings = | |
issuesToMap |> Seq.map ( fun row -> mapImportedIssue row fieldMappings ) | |
let mappedIssues = YoutrackIssues(Seq.toArray(mapImportedIssues importedIssues.Data mappings)) | |
let youtrackClient url = | |
let client = RestClient url | |
client.CookieContainer <- new System.Net.CookieContainer() | |
client | |
let yClient = youtrackClient Constants.YouTrackUrl | |
let signIn (client : RestClient) login password = | |
let request = RestRequest("rest/user/login", Method.POST) | |
.AddParameter("login", login, ParameterType.GetOrPost) | |
.AddParameter("password", password, ParameterType.GetOrPost) | |
client.Execute request | |
let sendIssue (client : RestClient) projectId issues = | |
let importUrl = sprintf "rest/import/%s/issues" projectId | |
let request = RestRequest(importUrl, Method.PUT) | |
request.RequestFormat <- RestSharp.DataFormat.Xml; | |
request.XmlSerializer <- RestSharp.Serializers.DotNetXmlSerializer(); | |
request.AddBody(issues) |> client.Execute | |
let LogFileName = sprintf @"YouTrackImportLog%s.txt" (System.DateTime.Now.ToString("yyyyMMdd-HHmmss")) | |
printf "%A" LogFileName | |
let writeLog(message : string) = | |
let currentTime = System.DateTime.Now.ToString() | |
use outp = System.IO.File.AppendText(LogFileName) in | |
(outp.WriteLine(sprintf "%s - %s" currentTime message)) | |
let LogResponse(response : IRestResponse) = | |
writeLog(sprintf "Status Code '%s'\r\nResponse:\r\n%s" (response.StatusCode.ToString()) response.Content) | |
writeLog("Starting import run") | |
let signInResponse = signIn yClient Constants.YouTrackAdminUserName Constants.YouTrackAdminPassword | |
LogResponse signInResponse | |
let importResponse = sendIssue yClient Constants.YouTrackProjectID mappedIssues | |
LogResponse importResponse | |
writeLog("Import run complete") | |
System.Diagnostics.Process.Start(LogFileName); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment