Skip to content

Commit 9edfb1b

Browse files
author
pgilmorepf
committed
JCU can now publish an SDK release
Summary: JCU can now publish an SDK release Main system provides cased and Lcased args to commands (needed for new command) VersionVarWriter command will now save the version information locally, and writing to file is optional (needed for new command) Main system GetArgVar utility now searches environment variables as well as command line. Added octokit package (needed for new command) Test Plan: Jenker! Reviewers: Marco.Williams Maniphest Tasks: T2633 Differential Revision: https://phab.playfabdev.com/D3035
1 parent 7376f4f commit 9edfb1b

10 files changed

+235
-69
lines changed

JenkinsConsoleUtility/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
packages/

JenkinsConsoleUtility/JenkinsConsoleUtility.csproj

+6
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@
3737
<StartupObject>JenkinsConsoleUtility.JenkinsConsoleUtility</StartupObject>
3838
</PropertyGroup>
3939
<ItemGroup>
40+
<Reference Include="Octokit, Version=0.23.0.0, Culture=neutral, processorArchitecture=MSIL">
41+
<HintPath>packages\Octokit.0.23.0\lib\net45\Octokit.dll</HintPath>
42+
<Private>True</Private>
43+
</Reference>
4044
<Reference Include="System" />
4145
<Reference Include="System.Core" />
4246
<Reference Include="System.Web" />
@@ -50,6 +54,7 @@
5054
<ItemGroup>
5155
<Compile Include="jcuSrc\AssemblyInfo.cs" />
5256
<Compile Include="jcuSrc\Commands\CloudScriptListener.cs" />
57+
<Compile Include="jcuSrc\Commands\GitApiCommand.cs" />
5358
<Compile Include="jcuSrc\Commands\KillTaskCommand.cs" />
5459
<Compile Include="jcuSrc\Commands\VersionVarWriter.cs" />
5560
<Compile Include="jcuSrc\JenkinsConsoleUtility.cs" />
@@ -83,6 +88,7 @@
8388
<ItemGroup>
8489
<None Include="app.config" />
8590
<None Include="jcuSrc\App.config" />
91+
<None Include="packages.config" />
8692
</ItemGroup>
8793
<ItemGroup>
8894
<Folder Include="Properties\" />

JenkinsConsoleUtility/JenkinsScripts/testInit.bat

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ nuget restore Server.sln
1212
popd
1313
call :forceCD "%WORKSPACE%"
1414
call :syncRepo SDKGenerator
15+
pushd SDKGenerator\JenkinsConsoleUtility
16+
nuget restore JenkinsConsoleUtility.sln
17+
popd
1518
call :syncRepo API_Specs
1619
call :forcePushD sdks
1720
call :syncRepo %SdkName%

JenkinsConsoleUtility/jcuSrc/Commands/CloudScriptListener.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ public class CloudScriptListener : ICommand
4444
private static CsGetRequest _getRequest;
4545
private static bool verbose;
4646

47-
public int Execute(Dictionary<string, string> args)
47+
public int Execute(Dictionary<string, string> argsLc, Dictionary<string, string> argsCased)
4848
{
49-
var titleId = GetTitleId(args);
50-
var buildIdentifier = JenkinsConsoleUtility.GetArgVar(args, "buildidentifier");
51-
var workspacePath = JenkinsConsoleUtility.GetArgVar(args, "workspacePath", Environment.GetEnvironmentVariable("TEMP"));
52-
var timeout = TimeSpan.FromSeconds(int.Parse(JenkinsConsoleUtility.GetArgVar(args, "timeout", "30")));
53-
verbose = bool.Parse(JenkinsConsoleUtility.GetArgVar(args, "verbose", "false"));
49+
var titleId = GetTitleId(argsLc);
50+
var buildIdentifier = JenkinsConsoleUtility.GetArgVar(argsLc, "buildidentifier");
51+
var workspacePath = JenkinsConsoleUtility.GetArgVar(argsLc, "workspacePath", Environment.GetEnvironmentVariable("TEMP"));
52+
var timeout = TimeSpan.FromSeconds(int.Parse(JenkinsConsoleUtility.GetArgVar(argsLc, "timeout", "30")));
53+
verbose = bool.Parse(JenkinsConsoleUtility.GetArgVar(argsLc, "verbose", "false"));
5454
_getRequest = new CsGetRequest { customId = buildIdentifier };
5555

5656
JenkinsConsoleUtility.FancyWriteToConsole("Begin CloudScriptListener", null, ConsoleColor.Gray);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using Octokit;
2+
using PlayFab.Json;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.IO;
6+
7+
namespace JenkinsConsoleUtility.Commands
8+
{
9+
class GitApiCommand : ICommand
10+
{
11+
private const string GitOwner = "PlayFab";
12+
private const string ProgramHeader = "JenkinsConsoleUtility";
13+
14+
// TODO: Validate this
15+
//private readonly Type[] _commandDependency = { typeof(VersionVarWriter) };
16+
//public Type[] CommandDependency { get { return _commandDependency; } }
17+
private readonly string[] _commandKeys = { "GitApi" };
18+
public string[] CommandKeys { get { return _commandKeys; } }
19+
private readonly string[] _mandatoryArgKeys = { "sdkName", "GITHUB_CREDENTIALS_FILE" };
20+
public string[] MandatoryArgKeys { get { return _mandatoryArgKeys; } }
21+
22+
public int Execute(Dictionary<string, string> argsLc, Dictionary<string, string> argsCased)
23+
{
24+
var sdkName = JenkinsConsoleUtility.GetArgVar(argsCased, "sdkName");
25+
var credsFilename = JenkinsConsoleUtility.GetArgVar(argsLc, "GITHUB_CREDENTIALS_FILE");
26+
if (!VersionVarWriter.set || !File.Exists(credsFilename))
27+
return 1;
28+
29+
var credsJson = File.ReadAllText(credsFilename);
30+
var creds = JsonWrapper.DeserializeObject<GitHubCredentials>(credsJson);
31+
32+
try
33+
{
34+
var header = new ProductHeaderValue(ProgramHeader);
35+
var client = new GitHubClient(header);
36+
client.Credentials = new Credentials(creds.token);
37+
var releaseRequest = new GitHubReleaseRequest(sdkName, VersionVarWriter.major, VersionVarWriter.minor, VersionVarWriter.date);
38+
var result = client.Repository.Release.Create(GitOwner, sdkName, releaseRequest).Result;
39+
if (!SeemsLegit(result, releaseRequest))
40+
return 1;
41+
42+
var sdkRepo = client.Repository.Get(GitOwner, sdkName).Result;
43+
JenkinsConsoleUtility.FancyWriteToConsole(sdkRepo.CloneUrl, null, ConsoleColor.Green);
44+
}
45+
catch (AggregateException agEx)
46+
{
47+
foreach (var e in agEx.InnerExceptions)
48+
JenkinsConsoleUtility.FancyWriteToConsole(e.ToString(), null, ConsoleColor.Red);
49+
return 1;
50+
}
51+
52+
return 0;
53+
}
54+
55+
private bool SeemsLegit(Release response, NewRelease request)
56+
{
57+
return response != null
58+
&& response.Url != null
59+
&& response.AssetsUrl != null
60+
&& response.UploadUrl != null
61+
&& response.HtmlUrl != null
62+
&& response.Id != 0
63+
&& response.TagName == request.TagName
64+
&& response.TargetCommitish == request.TargetCommitish
65+
&& response.Name == request.Name
66+
&& response.Draft == request.Draft
67+
&& response.Prerelease == request.Prerelease
68+
&& Math.Abs((response.CreatedAt - DateTime.UtcNow).TotalDays) < 2
69+
&& response.PublishedAt.HasValue
70+
&& Math.Abs((response.PublishedAt.Value - DateTime.UtcNow).TotalDays) < 2
71+
&& response.TarballUrl != null
72+
&& response.ZipballUrl != null
73+
&& response.Body == request.Body
74+
&& response.Author != null; // This one is a big object which ultimately says PlayFabJenkinsBot, but... if we got this far, it's probably right. :D
75+
}
76+
77+
private class GitHubCredentials
78+
{
79+
public string token;
80+
}
81+
82+
private class GitHubReleaseRequest : NewRelease
83+
{
84+
private const string TagFormat = "{major}.{minor}.{date}";
85+
private const string NameFormat = "{sdkName} version {major}.{minor}";
86+
private const string BodyFormat = "https://api.playfab.com/releaseNotes/#{date}";
87+
88+
public GitHubReleaseRequest(string sdkName, string major, string minor, string date) : base(TagFormat.Replace("{major}", major).Replace("{minor}", minor).Replace("{date}", date))
89+
{
90+
Name = NameFormat.Replace("{sdkName}", sdkName).Replace("{major}", major).Replace("{minor}", minor);
91+
Body = BodyFormat.Replace("{date}", date);
92+
TargetCommitish = "versioned";
93+
Draft = false;
94+
Prerelease = false;
95+
}
96+
}
97+
}
98+
}

JenkinsConsoleUtility/jcuSrc/Commands/KillTaskCommand.cs

+3-8
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,12 @@ public class KillTaskCommand : ICommand
1212

1313
private static readonly string[] MyCommandKeys = { "kill" };
1414
public string[] CommandKeys { get { return MyCommandKeys; } }
15-
private static readonly string[] MyMandatoryArgKeys = { "taskname" };
15+
private static readonly string[] MyMandatoryArgKeys = { "taskName" };
1616
public string[] MandatoryArgKeys { get { return MyMandatoryArgKeys; } }
1717

18-
public int Execute(Dictionary<string, string> inputs)
18+
public int Execute(Dictionary<string, string> argsLc, Dictionary<string, string> argsCased)
1919
{
20-
string taskName;
21-
if (!inputs.TryGetValue("taskname", out taskName))
22-
{
23-
JenkinsConsoleUtility.FancyWriteToConsole("Cannot find the process to kill", null, ConsoleColor.Red);
24-
return 1;
25-
}
20+
var taskName = JenkinsConsoleUtility.GetArgVar(argsLc, "taskName");
2621

2722
List<Process> hitList = new List<Process>();
2823
hitList.AddRange(Process.GetProcessesByName(taskName));

JenkinsConsoleUtility/jcuSrc/Commands/TestingCommand.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class TestingCommand : ICommand
1111
private static readonly string[] MyMandatoryArgKeys = { };
1212
public string[] MandatoryArgKeys { get { return MyMandatoryArgKeys; } }
1313

14-
public int Execute(Dictionary<string, string> inputs)
14+
public int Execute(Dictionary<string, string> argsLc, Dictionary<string, string> argsCased)
1515
{
1616
UUnitIncrementalTestRunner.Start(false, null, null, null);
1717
while (!UUnitIncrementalTestRunner.SuiteFinished)

JenkinsConsoleUtility/jcuSrc/Commands/VersionVarWriter.cs

+37-23
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,29 @@ namespace JenkinsConsoleUtility.Commands
88
{
99
public class VersionVarWriter : ICommand
1010
{
11-
private const string DefaultApiSpecFilePath = "../../../../API_Specs"; // Relative path to Generate.js
11+
private const string DefaultApiSpecFilePath = "../../../../API_Specs"; // Relative path from default VS output folder
1212
private const string DefaultApiSpecGitHubUrl = "https://raw.githubusercontent.com/PlayFab/API_Specs/master/";
1313
private const string DefaultApiSpecPlayFabUrl = "https://www.playfabapi.com/apispec/";
14-
private static string _apiSpecPath, _apiSpecGitUrl, _apiSpecPfUrl; // Exactly one of these is expected to be set
14+
private string _apiSpecPath, _apiSpecGitUrl, _apiSpecPfUrl; // Exactly one of these is expected to be set
1515

1616
private static readonly string[] MyCommandKeys = { "versionVarWriter", "version" };
1717
public string[] CommandKeys { get { return MyCommandKeys; } }
18-
private static readonly string[] MyMandatoryArgKeys = { "workspacePath", "destFile", "sdkName" };
18+
private static readonly string[] MyMandatoryArgKeys = { "sdkName" };
1919
public string[] MandatoryArgKeys { get { return MyMandatoryArgKeys; } }
2020

21-
public int Execute(Dictionary<string, string> args)
21+
// If this command runs, make the results accessible to other modules
22+
public static string sdkVersionString;
23+
public static string major;
24+
public static string minor;
25+
public static string date;
26+
public static bool set = false;
27+
28+
public int Execute(Dictionary<string, string> argsLc, Dictionary<string, string> argsCased)
2229
{
23-
var destFile = JenkinsConsoleUtility.GetArgVar(args, "destFile");
24-
var workspacePath = JenkinsConsoleUtility.GetArgVar(args, "workspacePath");
25-
var sdkName = JenkinsConsoleUtility.GetArgVar(args, "sdkName");
30+
string destFile, workspacePath;
31+
JenkinsConsoleUtility.TryGetArgVar(out destFile, argsLc, "destFile");
32+
JenkinsConsoleUtility.TryGetArgVar(out workspacePath, argsLc, "workspacePath");
33+
var sdkName = JenkinsConsoleUtility.GetArgVar(argsLc, "sdkName");
2634
var sdkGenKey = GetSdkGenKey(sdkName);
2735

2836
if (string.IsNullOrEmpty(sdkGenKey))
@@ -31,12 +39,12 @@ public int Execute(Dictionary<string, string> args)
3139
return 1;
3240
}
3341

34-
if (args.ContainsKey("apispecpath"))
35-
_apiSpecPath = JenkinsConsoleUtility.GetArgVar(args, "apiSpecPath");
36-
else if (args.ContainsKey("apispecgiturl"))
37-
_apiSpecGitUrl = JenkinsConsoleUtility.GetArgVar(args, "apiSpecGitUrl");
38-
else if (args.ContainsKey("apispecpfurl"))
39-
_apiSpecPfUrl = JenkinsConsoleUtility.GetArgVar(args, "apiSpecPfUrl");
42+
if (argsLc.ContainsKey("apispecpath"))
43+
_apiSpecPath = JenkinsConsoleUtility.GetArgVar(argsLc, "apiSpecPath");
44+
else if (argsLc.ContainsKey("apispecgiturl"))
45+
_apiSpecGitUrl = JenkinsConsoleUtility.GetArgVar(argsLc, "apiSpecGitUrl");
46+
else if (argsLc.ContainsKey("apispecpfurl"))
47+
_apiSpecPfUrl = JenkinsConsoleUtility.GetArgVar(argsLc, "apiSpecPfUrl");
4048
else
4149
{
4250
JenkinsConsoleUtility.FancyWriteToConsole("Api-Spec input not defined. Please input one of: apiSpecPath, apiSpecGitUrl, apiSpecPfUrl");
@@ -45,7 +53,6 @@ public int Execute(Dictionary<string, string> args)
4553

4654
var versionJson = GetApiJson("SdkManualNotes.json");
4755
var sdkNotes = JsonWrapper.DeserializeObject<SdkManualNotes>(versionJson);
48-
string sdkVersionString;
4956
if (!sdkNotes.sdkVersion.TryGetValue(sdkGenKey, out sdkVersionString))
5057
{
5158
JenkinsConsoleUtility.FancyWriteToConsole("SdkManualNotes.json does not contain: " + sdkGenKey);
@@ -54,20 +61,27 @@ public int Execute(Dictionary<string, string> args)
5461
}
5562

5663
var sdkPieces = sdkVersionString.Split('.');
57-
using (var outputFile = new StreamWriter(Path.Combine(workspacePath, destFile)))
64+
major = sdkPieces[0]; minor = sdkPieces[1]; date = sdkPieces[sdkPieces.Length - 1];
65+
set = true;
66+
67+
// Write this to a Jenkins environment variable file, if defined
68+
if (!string.IsNullOrEmpty(destFile))
5869
{
59-
outputFile.WriteLine("sdkVersion = " + sdkVersionString);
60-
outputFile.WriteLine("sdkDate = " + sdkPieces[sdkPieces.Length - 1]);
61-
JenkinsConsoleUtility.FancyWriteToConsole("sdkVersion = " + sdkVersionString);
62-
JenkinsConsoleUtility.FancyWriteToConsole("sdkDate = " + sdkPieces[sdkPieces.Length - 1]);
70+
using (var outputFile = new StreamWriter(Path.Combine(workspacePath, destFile)))
71+
{
72+
outputFile.WriteLine("sdkVersion = " + sdkVersionString);
73+
outputFile.WriteLine("sdkDate = " + date);
74+
JenkinsConsoleUtility.FancyWriteToConsole("sdkVersion = " + sdkVersionString);
75+
JenkinsConsoleUtility.FancyWriteToConsole("sdkDate = " + date);
76+
}
6377
}
6478
return 0;
6579
}
6680

6781
/// <summary>
6882
/// Fetch the given file based on the input settings (_apiSpecPath, _apiSpecGitUrl, or _apiSpecPfUrl)
6983
/// </summary>
70-
private static string GetApiJson(string filename)
84+
private string GetApiJson(string filename)
7185
{
7286
if (_apiSpecPath != null)
7387
{
@@ -100,7 +114,7 @@ private static string GetApiJson(string filename)
100114
/// This bit of hard coding is particularly bad, because it's arbitrary, and historically not entirely reliable
101115
/// We need a better resolution for this
102116
/// </summary>
103-
private static string GetSdkGenKey(string sdkName)
117+
private string GetSdkGenKey(string sdkName)
104118
{
105119
switch (sdkName.ToLower())
106120
{
@@ -127,7 +141,7 @@ private static string GetSdkGenKey(string sdkName)
127141
/// Convert a filename to a URL on the PlayFab API server
128142
/// - If Possible, else use GitHub.
129143
/// </summary>
130-
private static string GetPfServerUrl(string filename)
144+
private string GetPfServerUrl(string filename)
131145
{
132146
switch (filename.ToLower())
133147
{
@@ -155,7 +169,7 @@ private static string GetPfServerUrl(string filename)
155169
/// Wrap and synchronize a HTTPS-get call
156170
/// Converts a url into the corresponding string-file-contents
157171
/// </summary>
158-
private static async Task<string> SimpleHttpGet(string fullUrl)
172+
private async Task<string> SimpleHttpGet(string fullUrl)
159173
{
160174
if (string.IsNullOrEmpty(fullUrl))
161175
return "";

0 commit comments

Comments
 (0)