Skip to content

Commit c876c9f

Browse files
committed
Merge branch 'main' into production-change-control
2 parents 43c4b71 + cedb88b commit c876c9f

File tree

16 files changed

+356
-85
lines changed

16 files changed

+356
-85
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
ls $GITHUB_WORKSPACE/$artifact_dir
8686
8787
- name: Attach CE Artifact
88-
uses: actions/upload-artifact@v3
88+
uses: actions/upload-artifact@v4
8989
if: always()
9090
with:
9191
name: "PreIRISInstallationPackage"
@@ -103,7 +103,7 @@ jobs:
103103
fail: false
104104

105105
- name: Attach the report
106-
uses: actions/upload-artifact@v1
106+
uses: actions/upload-artifact@v4
107107
if: always()
108108
with:
109109
name: ${{ steps.xunit-viewer.outputs.report-name }}

CHANGELOG.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111
- New UI for the basic mode Sync (#415)
1212
- Allow changing namespaces and IPM package context from web UI (#280)
13+
- Support for editing repo from filesystem perspective via web application (#464)
14+
- Support for downloading a VSCode workspace file from web UI
15+
- IncrementalLoad pull event handler will update the running production, if any (#473)
1316

1417
### Fixed
1518
- Instance wide settings are placed in proper global (#444)
19+
- Avoid delay/errors in loading interop JS when there is a URL prefix (e.g., instance name in multi-instance webserver configuration)
20+
- Added proper JS escaping in sync output
21+
- Added support to switch branch in basic mode from menu (#451)
22+
- Pull event handler will not fail when change set includes unmapped files (#453)
23+
- Pull event handler will attempt compile even if there are failures to load (#457)
24+
- Improved logging in preview and when errors occur via WebSocket commands (#467)
25+
- Fixed pull event handler handling of extremely long class names from diff (#467)
1626

1727
## [2.4.1] - 2024-08-02
1828

@@ -161,5 +171,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
161171
- #201: fix behavior with CSP files
162172

163173
## [2.0.1] - 2022-06-02
164-
- Last released version before CHANGELOG existed.
165-
174+
- Last released version before CHANGELOG existed.

cls/SourceControl/Git/Extension.cls

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,13 @@ Method AfterUserAction(Type As %Integer, Name As %String, InternalName As %Strin
7474
if menu '= "%SourceMenu", menu'="%SourceContext" {
7575
quit $$$OK
7676
}
77-
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
77+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName, .fromWebApp)
7878
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
7979
set ec = ##class(SourceControl.Git.Utils).AfterUserAction(Type, Name, InternalName, .Answer, .Msg, .Reload)
80+
if fromWebApp {
81+
// Force reload and compile of actual item if underlying file has changed
82+
do ..OnBeforeLoad(InternalName,1,1)
83+
}
8084
quit ec
8185
}
8286

@@ -125,6 +129,7 @@ Method OnSourceMenuItem(name As %String, ByRef Enabled As %String, ByRef Display
125129
"Status": 1,
126130
"GitWebUI" : 1,
127131
"NewBranch": 1,
132+
"SwitchBranch": 1,
128133
"Sync": 1,
129134
"": 1,
130135
:-1
@@ -234,12 +239,12 @@ Method OnMenuItem(MenuName As %String, InternalName As %String, SelectedText As
234239

235240
/// This is called before the actual load of data to give the chance
236241
/// to load the item from an external format.
237-
Method OnBeforeLoad(InternalName As %String, verbose As %Boolean) As %Status
242+
Method OnBeforeLoad(InternalName As %String, verbose As %Boolean, compile As %Boolean = 0) As %Status
238243
{
239244
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
240245
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
241246
if ##class(SourceControl.Git.Utils).IsInSourceControl(InternalName) {
242-
quit ##class(SourceControl.Git.Utils).ImportItem(InternalName,,0)
247+
quit ##class(SourceControl.Git.Utils).ImportItem(InternalName,,0,compile)
243248
}
244249
quit $$$OK
245250
}
@@ -274,7 +279,7 @@ Method OnAfterSave(InternalName As %String, Object As %RegisteredObject = {$$$NU
274279
set sc = $$$OK
275280
quit:$get(%gscSkipSaveHooks) sc
276281
try {
277-
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(.InternalName)
282+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(.InternalName,.fromWebApp,.fullExternalName)
278283
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
279284
if ##class(SourceControl.Git.Utils).IsNamespaceInGit() {
280285
// If this is a production class and production decomposition is enabled, call recursively on all modified production items.
@@ -297,11 +302,18 @@ Method OnAfterSave(InternalName As %String, Object As %RegisteredObject = {$$$NU
297302
}
298303
}
299304
if ..IsInSourceControl(InternalName) {
300-
set filename = ##class(SourceControl.Git.Utils).FullExternalName(InternalName)
301-
$$$ThrowOnError(##class(SourceControl.Git.Utils).RemoveRoutineTSH(InternalName))
302-
$$$ThrowOnError(##class(SourceControl.Git.Utils).ExportItem(InternalName))
303-
if '##class(SourceControl.Git.Change).IsUncommitted(filename) {
304-
$$$ThrowOnError(##class(SourceControl.Git.Change).SetUncommitted(filename, "edit", InternalName, $username, "", 1, "", "", 0))
305+
if fromWebApp {
306+
if fullExternalName = ##class(SourceControl.Git.Utils).FullExternalName(InternalName) {
307+
// Reimport item into database
308+
$$$ThrowOnError(##class(SourceControl.Git.Utils).ImportItem(InternalName,,1,1))
309+
}
310+
} else {
311+
set filename = ##class(SourceControl.Git.Utils).FullExternalName(InternalName)
312+
$$$ThrowOnError(##class(SourceControl.Git.Utils).RemoveRoutineTSH(InternalName))
313+
$$$ThrowOnError(##class(SourceControl.Git.Utils).ExportItem(InternalName))
314+
if '##class(SourceControl.Git.Change).IsUncommitted(filename) {
315+
$$$ThrowOnError(##class(SourceControl.Git.Change).SetUncommitted(filename, "edit", InternalName, $username, "", 1, "", "", 0))
316+
}
305317
}
306318
}
307319
}
@@ -452,3 +464,4 @@ Method AddToSourceControl(InternalName As %String, Description As %String = "")
452464
}
453465

454466
}
467+

cls/SourceControl/Git/PullEventHandler/IncrementalLoad.cls

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,38 @@ Parameter DESCRIPTION = "Performs an incremental load and compile of all changes
99

1010
Method OnPull() As %Status
1111
{
12-
set loadSC = $$$OK
12+
set sc = $$$OK
1313
set nFiles = 0
1414

1515
for i=1:1:$get(..ModifiedFiles){
1616
set internalName = ..ModifiedFiles(i).internalName
1717
if ((internalName = "") && (..ModifiedFiles(i).changeType '= "D")) {
1818
write !, ..ModifiedFiles(i).externalName, " was not imported into the database and will not be compiled. "
1919
} elseif (..ModifiedFiles(i).changeType = "D") {
20-
set sc = ..DeleteFile(internalName, ..ModifiedFiles(i).externalName)
21-
if sc {
20+
set delSC = ..DeleteFile(internalName, ..ModifiedFiles(i).externalName)
21+
if delSC {
2222
write !, ..ModifiedFiles(i).externalName, " was deleted."
2323
} else {
2424
write !, "WARNING: Deletion of ", ..ModifiedFiles(i).externalName, " failed."
2525
}
2626
} else {
2727
set compilelist(internalName) = ""
2828
set nFiles = nFiles + 1
29-
set loadSC = $$$ADDSC(loadSC,##class(SourceControl.Git.Utils).ImportItem(internalName, 1))
30-
$$$ThrowOnError(loadSC)
29+
set sc = $$$ADDSC(sc,##class(SourceControl.Git.Utils).ImportItem(internalName, 1))
3130
}
3231
}
3332

3433
if (nFiles = 0) {
3534
write !, "Nothing to compile."
3635
quit $$$OK
3736
}
38-
quit $system.OBJ.CompileList(.compilelist, "ck")
37+
set sc = $$$ADDSC(sc,$system.OBJ.CompileList(.compilelist, "ck"))
38+
if $$$comClassDefined("Ens.Director") && ##class(Ens.Director).IsProductionRunning() {
39+
write !,"Updating production... "
40+
set sc = $$$ADDSC(sc,##class(Ens.Director).UpdateProduction())
41+
write "done."
42+
}
43+
quit sc
3944
}
4045

4146
Method DeleteFile(item As %String = "", externalName As %String = "") As %Status

cls/SourceControl/Git/Settings.cls

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ Property defaultMergeBranch As %String [ InitialExpression = {##class(SourceCont
5050
/// Compile using the configured pull event handler when "Import All" is run
5151
Property compileOnImport As %Boolean [ InitialExpression = {##class(SourceControl.Git.Utils).CompileOnImport()} ];
5252

53+
/// Define a namespace-level web application allowing access to multiple git repos across separate namespaces
54+
Property namespaceLevelGitWebApp As %Boolean [ InitialExpression = {##class(SourceControl.Git.Settings).HasNamespaceWebApp()} ];
55+
5356
Property Mappings [ MultiDimensional ];
5457

5558
Method %OnNew() As %Status
@@ -228,6 +231,75 @@ ClassMethod Configure() As %Boolean [ CodeMode = objectgenerator ]
228231
do %code.WriteLine(" quit 1")
229232
}
230233

234+
Method ConfigureNamespaceWebApplication()
235+
{
236+
Set root = ##class(%Library.File).NormalizeDirectory(##class(SourceControl.Git.Utils).TempFolder())
237+
Set deleteWebApp = ..HasNamespaceWebApp(.appDirectory) && '..namespaceLevelGitWebApp
238+
Set createWebApp = ..namespaceLevelGitWebApp && '..HasNamespaceWebApp()
239+
Do ..WebAppOperation("/git/"_$Namespace_"/", createWebApp, deleteWebApp, root)
240+
}
241+
242+
Method WebAppOperation(name, create As %Boolean, delete As %Boolean, root As %String) [ Private ]
243+
{
244+
Set namespace = $Namespace
245+
New $Namespace
246+
Set $Namespace = "%SYS"
247+
If $Extract(name) = "/" {
248+
Set name = $Extract(name,1,*-1)
249+
}
250+
If delete {
251+
If ##class(Security.Applications).Exists(name) {
252+
$$$ThrowOnError(##class(Security.Applications).Delete(name))
253+
Write !,"Removed web application "_name
254+
}
255+
Quit
256+
}
257+
258+
// These are the only things we want to coerce.
259+
Set props("AutheEnabled")=0 // No auth methods enabled = impossible to use
260+
Set props("InbndWebServicesEnabled")=0
261+
Set props("ServeFiles")=0
262+
Set props("Enabled")=1
263+
Set props("Name")=name
264+
Set props("NameSpace")=namespace
265+
Set props("Path")=root
266+
Set props("Type")=2
267+
Set props("Recurse")=1
268+
If create {
269+
Write !,"Creating web application: "_name_"... "
270+
$$$ThrowOnError(##class(Security.Applications).Create(name,.props))
271+
Write "done."
272+
} ElseIf ##class(Security.Applications).Exists(name) {
273+
Write !,"Web application '"_name_"' already exists."
274+
$$$ThrowOnError(##class(Security.Applications).Get(name,.existingProps))
275+
Set changes = 0
276+
Set key = ""
277+
For {
278+
Set key = $Order(props(key),1,value)
279+
Quit:key=""
280+
If (value '= $Get(existingProps(key))) {
281+
Write !,"Changing "_key_": "_$Get(existingProps(key))_" -> "_value
282+
Set changes = 1
283+
}
284+
}
285+
If changes {
286+
$$$ThrowOnError(##class(Security.Applications).Modify(name,.props))
287+
Write !,"Web application '"_name_"' updated."
288+
} Else {
289+
Write !,"No changes made to web application."
290+
}
291+
}
292+
}
293+
294+
ClassMethod HasNamespaceWebApp(Output webAppDirectory) As %Boolean
295+
{
296+
Set webAppDirectory = $System.CSP.GetFileName("/git/"_$Namespace_"/")
297+
If (webAppDirectory '= "") {
298+
Set webAppDirectory = ##class(%Library.File).NormalizeDirectory(webAppDirectory)
299+
}
300+
Quit (webAppDirectory '= "")
301+
}
302+
231303
Method OnAfterConfigure() As %Boolean
232304
{
233305
set defaultPromptFlag = $$$DisableBackupCharMask + $$$TrapCtrlCMask + $$$EnableQuitCharMask + $$$DisableHelpCharMask + $$$DisableHelpContextCharMask + $$$TrapErrorMask
@@ -254,6 +326,8 @@ Method OnAfterConfigure() As %Boolean
254326
}
255327
}
256328

329+
do ..ConfigureNamespaceWebApplication()
330+
257331
set gitDir = ##class(%File).NormalizeDirectory(..namespaceTemp)_".git"
258332
if '##class(%File).DirectoryExists(gitDir) {
259333
set list(1) = "Initialize empty repo"

cls/SourceControl/Git/StreamServer.cls

Lines changed: 1 addition & 2 deletions
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()
10+
set sourceControlInclude = ##class(SourceControl.Git.Utils).GetSourceControlInclude(%request.URLPrefix)
1111
while '%stream.AtEnd {
1212
set text = %stream.Read()
1313
set text = $replace(text,"{{baseHref}}",..EscapeHTML(%base))
@@ -19,4 +19,3 @@ ClassMethod OnPage() As %Status
1919
}
2020

2121
}
22-

0 commit comments

Comments
 (0)