Skip to content

Commit e6479a8

Browse files
committed
Merge branch 'main' into production-change-control
2 parents c34fa58 + a642f94 commit e6479a8

27 files changed

+259
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111
- Added 'git push --force' in expert mode (#527)
12+
- Add remote repository to settings page (#448)
13+
- Added environment awareness in configuration, and showing of environment name in UI (#124)
1214

1315
### Fixed
1416
- Fixed display of other users' username in workspace view on Unix (#530)
17+
- Fixed slowness loading some CSP pages with multiple instances sharing a webserver (#540)
1518

1619
## [2.6.0] - 2024-10-07
1720

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@
3434
3535
## Basic Use
3636
37+
### Source Control
38+
39+
For those with less experience using source control, we recommend this [page](/docs/scintro.md) for a quick introduction to source control / change control basics.
40+
41+
### Health Connect Cloud
42+
git-source control is the recommended source control for Health Connect Cloud. [This page](/docs/hcc.md) covers HCC specific usage of git-source-control, including the recommended development workflow, initial setup, and CICD pipelining.
43+
3744
### Studio
3845
Add a file for tracking by right-clicking on it in the workspace/project view and choosing Git > Add.
3946
This same menu also has options to remove (stop tracking the file), discard changes (revert to the index), or commit changes.

cls/SourceControl/Git/Settings.cls

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ Property namespaceLevelGitWebApp As %Boolean [ InitialExpression = {##class(Sour
5959
/// Warn when an item has uncommitted changes in a different namespace in this instance
6060
Property warnInstanceWideUncommitted As %Boolean [ InitialExpression = {##class(SourceControl.Git.Utils).WarnInstanceWideUncommitted()} ];
6161

62+
/// The name of the environment (DEVELOPMENT, TEST, LIVE)
63+
Property environmentName As %String(MAXLEN = "") [ InitialExpression = {##class(SourceControl.Git.Utils).EnvironmentName()} ];
64+
6265
Property Mappings [ MultiDimensional ];
6366

6467
Method %OnNew() As %Status
@@ -146,11 +149,19 @@ Method %Save() As %Status
146149
set @storage@("settings", "compileOnImport") = ..compileOnImport
147150
set @storage@("settings", "warnInstanceWideUncommitted") = ..warnInstanceWideUncommitted
148151
set @storage@("settings", "basicMode") = ..systemBasicMode
152+
set @storage@("settings", "environmentName") = ..environmentName
149153
if ..basicMode = "system" {
150154
kill @storage@("settings", "user", $username, "basicMode")
151155
} else {
152156
set @storage@("settings", "user", $username, "basicMode") = ..basicMode
153157
}
158+
try {
159+
do $SYSTEM.Version.SystemMode(..environmentName)
160+
} catch e {
161+
// no-op; user might not have privileges.
162+
}
163+
164+
154165

155166
// update value of basicUserMode to reflect the updated setting for basicMode
156167
set ..userBasicMode = ##class(SourceControl.Git.Utils).UserBasicMode()
@@ -257,6 +268,13 @@ ClassMethod Configure() As %Boolean [ CodeMode = objectgenerator ]
257268
do %code.WriteLine(" if value = ""System's Default Mode"" { set value = ""system""}")
258269
do %code.WriteLine(" elseif value = ""Yes"" { set value = 1}")
259270
do %code.WriteLine(" elseif value = ""No"" { set value = 0}")
271+
} elseif ((propertyDef) && (propertyDef.Name = "environmentName")) {
272+
do %code.WriteLine(" set list(1) = ""DEVELOPMENT""")
273+
do %code.WriteLine(" set list(2) = ""TEST""")
274+
do %code.WriteLine(" set list(3) = ""LIVE""")
275+
do %code.WriteLine(" set list(4) = ""FAILOVER""")
276+
do %code.WriteLine(" set list(5) = """"")
277+
do %code.WriteLine(" set response = ##class(%Library.Prompt).GetArray("_promptQuoted_",.value,.list,,,,"_defaultPromptFlag_")")
260278
} else {
261279
do %code.WriteLine(" set response = ##class(%Library.Prompt).GetString("_promptQuoted_",.value,,,,"_defaultPromptFlag_")")
262280
}

cls/SourceControl/Git/StreamServer.cls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Class SourceControl.Git.StreamServer Extends %CSP.StreamServer
77
ClassMethod OnPage() As %Status
88
{
99
if (%stream '= $$$NULLOREF) && $data(%base)#2 {
10-
set sourceControlInclude = ##class(SourceControl.Git.Utils).GetSourceControlInclude(%request.URLPrefix)
10+
set sourceControlInclude = ##class(SourceControl.Git.Utils).GetSourceControlInclude()
1111
while '%stream.AtEnd {
1212
set text = %stream.Read()
1313
set text = $replace(text,"{{baseHref}}",..EscapeHTML(%base))

cls/SourceControl/Git/Utils.cls

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,16 @@ ClassMethod WarnInstanceWideUncommitted() As %Boolean
173173
quit $get(@..#Storage@("settings","warnInstanceWideUncommitted"),1)
174174
}
175175

176+
ClassMethod EnvironmentName() As %String
177+
{
178+
quit $SYSTEM.Version.SystemMode()
179+
}
180+
181+
ClassMethod IsLIVE() As %Boolean
182+
{
183+
quit ..EnvironmentName()="LIVE"
184+
}
185+
176186
ClassMethod NeedSettings() As %Boolean [ CodeMode = expression ]
177187
{
178188
(..TempFolder() = "") || (..GitBinPath() = "") || (..GitBinPath() = """")
@@ -2639,7 +2649,7 @@ ClassMethod GetPackageVersion() As %String [ CodeMode = objectgenerator ]
26392649
quit $$$OK
26402650
}
26412651

2642-
ClassMethod GetSourceControlInclude(prefix As %String = "") As %String
2652+
ClassMethod GetSourceControlInclude(prefix As %String = {%request.URLPrefix}) As %String
26432653
{
26442654
quit $select(##class(%Library.EnsembleMgr).IsEnsembleInstalled():
26452655
"<script type=""text/javascript"" src="""_prefix_"/isc/studio/templates/ensemble/Ens_SourceControl.js""></script>",
@@ -2877,4 +2887,28 @@ ClassMethod BaselineExport(pCommitMessage = "", pPushToRemote = "") As %Status
28772887
return sc
28782888
}
28792889

2890+
/// Returns the url for the remote repository (censoring the username)
2891+
ClassMethod GetConfiguredRemote() As %String
2892+
{
2893+
d ..RunGitCommand("remote",.err,.out,"-v")
2894+
set line = out.ReadLine()
2895+
set url = $piece($piece(line,$char(9),2)," ",1)
2896+
return url
2897+
}
2898+
2899+
ClassMethod GetRedactedRemote() As %String
2900+
{
2901+
set url = ..GetConfiguredRemote()
2902+
set username= $piece($piece(url,":",3),"@",1)
2903+
set censoredUrl = $replace(url, username,"*******")
2904+
return censoredUrl
2905+
}
2906+
2907+
ClassMethod SetConfiguredRemote(url) As %String
2908+
{
2909+
do ##class(SourceControl.Git.Utils).RunGitCommandWithInput("remote",,.errStream,.outStream,"set-url","origin",url)
2910+
set output = outStream.ReadLine(outStream.Size)
2911+
quit output
2912+
}
2913+
28802914
}

cls/SourceControl/Git/WebUIDriver.cls

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ ClassMethod HandleRequest(pagePath As %String, InternalName As %String = "", Out
2626
set responseJSON = {
2727
"url": (..GetHomeURL())
2828
}
29+
} elseif $extract(pagePath,6,*) = "remote" {
30+
set responseJSON = ..GetRemote()
31+
} elseif $extract(pagePath,6,*) = "environment" {
32+
set responseJSON = {
33+
"environment": (##class(SourceControl.Git.Utils).EnvironmentName())
34+
}
2935
} else {
3036
set %response.Status = ##class(%CSP.REST).#HTTP404NOTFOUND
3137
set responseJSON = {"error":("invalid URI: " _ pagePath)}
@@ -407,4 +413,10 @@ ClassMethod GetHomeURL() As %String
407413
quit prefix_"/csp/sys/UtilHome.csp"
408414
}
409415

416+
ClassMethod GetRemote() As %Library.DynamicObject
417+
{
418+
set remote = ##class(SourceControl.Git.Utils).GetRedactedRemote()
419+
quit {"remote": (remote)}
420+
}
421+
410422
}

csp/gitprojectsettings.csp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,14 @@ body {
7979
set homeURL = ##class(SourceControl.Git.WebUIDriver).GetHomeURL()
8080

8181
set settings = ##class(SourceControl.Git.Settings).%New()
82+
set remote = ##class(SourceControl.Git.Utils).GetRedactedRemote()
83+
/// After Save
8284
if (%request.Method="POST") && $Data(%request.Data("gitsettings",1)) {
8385
for param="gitUserName","gitUserEmail" {
8486
set $Property(settings,param) = $Get(%request.Data(param,1))
8587
}
8688
if ('settings.settingsUIReadOnly) {
87-
for param="gitBinPath","namespaceTemp","privateKeyFile","pullEventClass","percentClassReplace", "defaultMergeBranch" {
89+
for param="gitBinPath","namespaceTemp","privateKeyFile","pullEventClass","percentClassReplace", "defaultMergeBranch","environmentName" {
8890
set $Property(settings,param) = $Get(%request.Data(param,1))
8991
}
9092

@@ -94,6 +96,12 @@ body {
9496
set settings.mappedItemsReadOnly = 0
9597
}
9698

99+
set newRemote = $Get(%request.Data("remoteRepo",1))
100+
// If entry was modified, set new remote repo
101+
if (newRemote '= ##class(SourceControl.Git.Utils).GetRedactedRemote()) {
102+
do ##class(SourceControl.Git.Utils).SetConfiguredRemote(newRemote)
103+
}
104+
97105
set settings.compileOnImport = ($Get(%request.Data("compileOnImport", 1)) = 1)
98106
set settings.decomposeProductions = ($Get(%request.Data("decomposeProductions", 1)) = 1)
99107
set settings.decomposeProdAllowIDE = ($Get(%request.Data("decomposeProdAllowIDE", 1)) = 1)
@@ -308,6 +316,20 @@ body {
308316
</div>
309317
</div>
310318

319+
<div class="form-group row mb-3">
320+
<label for="environmentName" class="offset-sm-1 col-sm-3 col-form-label" data-toggle="tooltip" data-placement="top" title="Environment Name">Environment Name</label>
321+
<div class="col-sm-7">
322+
<select class="form-control" id="environmentName" name="environmentName">
323+
<server>
324+
for envName = "TEST","DEVELOPMENT","LIVE","FAILOVER","" {
325+
// create option with envName, set selected if envName == current environmentName
326+
&html<<option #($CASE(envName, settings.environmentName: "selected", :""))# value=#(envName)#>#(envName)# </option>>
327+
}
328+
</server>
329+
</select>
330+
</div>
331+
</div>
332+
311333
<div class="form-group row mb-3">
312334
<label for="percentClassReplace" class="offset-sm-1 col-sm-3 col-form-label" data-toggle="tooltip" data-placement="top" title="Character(s) to replace '%' with for percent classes while exporting them out to the filesystem. By default, the '%' is removed.">'%' Replacement on Export</label>
313335
<div class="col-sm-7">
@@ -342,6 +364,16 @@ body {
342364
<input type="text" class="form-control" id="defaultMergeBranch" name="defaultMergeBranch" value='#(..EscapeHTML(settings.defaultMergeBranch))#' placeholder="sample-remote-branch">
343365
</div>
344366
</div>
367+
368+
<div class="form-group row mb-3">
369+
<label for="remoteRepo" class="offset-sm-1 col-sm-3 col-form-label" data-toggle="tooltip" data-placement="top" title="Url to Remote repository">Remote Repository</label>
370+
<div class="col-sm-7">
371+
<input type="text" class="form-control" id="remoteRepo" name="remoteRepo" value='#(..EscapeHTML(remote))#' placeholder="ex. [email protected]:User/UserRepo.git"/>
372+
<div class = "neutral-feedback">
373+
(Username is redacted)
374+
</div>
375+
</div>
376+
</div>
345377

346378
<div class="form-group row mb-3">
347379
<label for="mappedItemsReadOnly" class="offset-sm-1 col-sm-3 col-form-label" data-toggle="tooltip" data-placement="top" title="Whether items mapped from a database other than this namespace's default routine database should be read-only. If enabled, mapped items won't be saved to source control or exported. NOTE: These are different from the mappings configured in this settings page"> Treat Mapped Items as Read-only</label>

docs/expert.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
### Feature branches
2+
3+
The first step in making changes in Health Connect Cloud using git-source-control is making a feature branch. In order for changes to be tracked by source control properly, each change (also called a feature) should be made on it's own branch, so as to not interfere with other changes, and allow for testing of its effects on the production environment. To create a new feature branch, navigate to the Git UI in the namespace you plan on doing development.
4+
5+
First, make sure that you are in the development branch. It should be bolded and at the top of the Local Branches in the sidebar. If it is not, as pictured below, click on the "development" branch and press checkout branch.
6+
7+
![Development branch in Git UI Sidebar](images/hcc/developmentsidebar.png)
8+
9+
Once you are in the development branch, press the "+" next the the Local Branches tab, and create a new branch by typing out a name for it. (No spaces or special characters are allowed in branch names).
10+
11+
![Creating a new via sidebar](images/hcc/newbranch.png)
12+
![Naming new branch](images/hcc/newbranchnaming.png)
13+
14+
Finally, you should click on the new branch you just made in the sidebar, and then press "Push".
15+
16+
![Push your new branch](images/hcc/pushbranch.png)
17+
18+
This makes sure that your branch will be tracked in Gitlab, so that other users can checkout your branch to test your changes on their own namespaces.
19+
20+
After this, you can start working on the change.
21+
22+
### Merge Requests
23+
24+
Once you have made all the changes for the specific feature you are working on, and have tested in your namespace, it will be time to merge all of these changes into the development branch. To start, make sure that all your changes have been commited to your feature branch. To do this, navigate to the Git UI, and after making sure you are in the right feature branch, press the "Workspace" tab at the top of the sidebar.
25+
26+
![Workspace tab in the sidebar](images/hcc/sidebar.png)
27+
28+
This will bring you to the workspace view. All the changes you made to files should be in the bottom left of the workspace view. ![Changed files in workspace](images/hcc/workspacechanges.png)
29+
30+
Clicking on one of these files will bring up a line by line view of the changes that have been made. Make sure that these are the changes you want to make, and then select all the files. Next, enter a commit message that should describe that changes that have been made.
31+
32+
![Enter commit message](images/hcc/commitmessage.png)
33+
34+
You can enter more details below, and then press the commit button underneath. This will commit the changes you have made to your feature branch. Once all of your changes have been committed, you should be ready to merge into the development branch.
35+
36+
In the Git UI, first checkout the development branch, by selecting it from the Local Branches and pressing "Checkout branch". Next, find the feature branch that you have been working on, select it from the local branches, and press "Merge Branch".
37+
38+
![Merge Branch](images/hcc/mergebranch.png)
39+
40+
41+
42+

docs/hcc.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# git-source-control for Health Connect Cloud Overview
2+
3+
## Development Workflow
4+
5+
git-source-control has two main use modes: Basic and Expert. For Health Connect Cloud, we recommend beginning with Basic Mode, since it includes all of the necessary functionality for proper source control development while being easy to use for those with less Git experience. The recommended workflow for Health Connect Cloud is to create interface branches, create merge requests into development, and then pull the changes into the main dev development namespace.
6+
7+
A Health Connect Cloud Dev deployment will have a main namespace (which is also present in Test and Prod) and should also have a dedicated namespace for each developer contributing. These namespaces can be configured via the Cloud Portal. It is important for changes to originate in developer-specific namespaces; the main namespace in the dev deployment should always be kept up to date with the development branch in GitLab, either through a CI/CD pipeline or by use of the Git Pull page from git-source-control.
8+
9+
### Interface Branches
10+
11+
The first step in making changes in Health Connect Cloud using git-source-control is making an interface (feature) branch. To start out, you should be in your own personal development namespace. In order for changes to be tracked by source control properly, each change (also called a feature) should be made on it's own branch, so as to not interfere with other changes, and allow for testing of its effects on the production environment. To create a new feature branch, use the source control menu and select "Create new branch".
12+
13+
![Creating a new branch](images/hcc/newbranchmenu.png)
14+
15+
You will be prompted to enter a name for your new branch (no spaces or special characters), after which your environment will switch to that new branch. All new branches are fresh copies of the development branch. We recommend that you name branches descriptively based on a reference to the issue/bug that you are trying to fix - a GitLab issue number, Jira, ServiceNow ticket reference, etc.
16+
17+
### Making Changes
18+
19+
Now that you are in your new branch (you can see your current branch in the first item in the source control menu), you can start making changes. As you make changes to different business processes, rules, and productions, make sure that all of these changes are saved properly and any new items are added to source control (via the "Add" menu item) before you continue to sync and merge.
20+
21+
### Syncing and Merge Requests
22+
23+
Once you have made all the changes for the specific feature you are working on, and have tested in your namespace, it will be time to merge all of these changes into the development branch.
24+
25+
To start, press the sync button from the source control menu.
26+
27+
![Sync option in menu](images/hcc/sync.png)
28+
29+
This will bring up the sync interface, where you are able to see all the of the files you have changed, as well as add a descriptive comment for the changes you made. When you sync, these changes will be pushed to the git remote.
30+
31+
![Sync Interface](images/hcc/syncinterface.png)
32+
33+
Use the link in the output of the sync in order to create a merge request in the git remote (don't worry if you close out of the sync tab, you can also navigate to GitLab manually). Here, you should make sure that you are merging your interface branch into the development environment, and notify / add the relevant reviewers. Once this merge request is approved, it will be merged into the development branch, so that all of your changes will now be a part of development.
34+
35+
### Switching Branches
36+
37+
Suppose you begin working on a larger project in one branch, and then need to shift to something else. The proper approach to this in git-source-control is to commit your in-progress work on the first interface, and then to switch to a new branch. This branch will be based on the development branch and may be missing components from the first project, but that's OK. You can always switch back to the first interface branch to continue work there.
38+
39+
## Deploying Changes to the Main Dev Namespace
40+
41+
If you are using a CI/CD pipeline in GitLab, simply merging the feature branch to development is enough; your change will be deployed to the main development namespace automatically.
42+
43+
If you are not using a CI/CD pipeline, you can get merged changes into the main development namespace using the "Git Pull" link from the Favorites section in the Health Connect Cloud home page. This will load and compile the incremental set of changes from new commits to the development branch.
44+
45+
## Deploying Changes to Test and Prod
46+
47+
### Deploying using CI/CD Pipelines
48+
49+
With CI/CD pipelines in place, the most important thing is that there is a branch in GitLab that corresponds to the main namespace in Test and another that corresponds to the main namespace on Prod, so that you can see exactly when changes made it to each branch/environment. With CI/CD pipelines, there's no action needed to move the change forward - merging the merge request is sufficient. The recommended workflow for this is to create additional merge requests from the interface branch to each of Test and Prod. Other Git branching and change flows may be appropriate if you have a strong opinion about them.
50+
51+
### Deploying using the Deployment Manager
52+
53+
Another way to move work from the main Dev namespace to the corresponding namespace in Test and Prod environments is using the Deployment Manager to move from Dev to Test, then Test to Prod. This loses the traceability of a clean branch-to-environment mapping, but is perhaps simpler technically and involves less time wrangling merge requests in GitLab. For guidance on using the deployment manager, see [InterSystems Documentation](https://docs.intersystems.com/irisforhealthlatest/csp/docbook/Doc.View.cls?KEY=EGDV_deploying).

docs/images/basicmodesetting.png

23.1 KB
Loading

0 commit comments

Comments
 (0)