Merge pull request #52 from jdaugherty/target_folder_support

#50 - add TARGET_FOLDER support to github documentation deployment ac…
diff --git a/deploy-github-pages/README.md b/deploy-github-pages/README.md
index 70eb3eb..d2b3f12 100644
--- a/deploy-github-pages/README.md
+++ b/deploy-github-pages/README.md
@@ -39,6 +39,7 @@
 * (required for release) `VERSION` - the version of the documentation being deployed. Must be a [Semantic Version](https://semver.org/). This is required for release documentation publishing only.
 * (optional) `DOCUMENTATION_BRANCH` - the branch to which the documentation files will be copied. Defaults to `gh-pages`.
 * (optional) `GH_TOKEN` - the GitHub token to use for authentication. If not provided, the action will use the default GitHub token available in the environment.
+* (optional) `TARGET_FOLDER` - defaults to the root of the `DOCUMENTATION_BRANCH`, allows for specifying a base path for documentation.
 * (optional) `TARGET_SUBFOLDER` - if specified, a nested subfolder will be created with this name in any documentation folder.
 * (optional) `LAST_RELEASE_FOLDER` - the `latest` folder name for a release. Defaults to `latest`.
 * (optional) `LAST_SNAPSHOT_FOLDER` - the `snapshot` folder name for a snapshot. Defaults to `snapshot`.
diff --git a/deploy-github-pages/entrypoint.sh b/deploy-github-pages/entrypoint.sh
index 457264c..e9e186d 100755
--- a/deploy-github-pages/entrypoint.sh
+++ b/deploy-github-pages/entrypoint.sh
@@ -165,6 +165,10 @@
 # SOURCE_FOLDER - the relative path of the source documentation folder from the root of the repo
 set_path_value_or_error "${SOURCE_FOLDER}" "" "SOURCE_FOLDER"
 
+# TARGET_FOLDER - the base folder to publish documentation to
+set_path_value_or_error "${TARGET_FOLDER}" "." "TARGET_FOLDER"
+mkdir -p "${TARGET_FOLDER}"
+
 # TARGET_SUBFOLDER - an optional sub folder to publish to
 set_path_value_or_error "${TARGET_SUBFOLDER}" "." "TARGET_SUBFOLDER"
 if [ "${TARGET_SUBFOLDER}" == "." ]; then
@@ -230,11 +234,11 @@
   echo "Snapshot detected"
 
   # Subfolder support
-  BASE_PUBLISH_PATH="./${LAST_SNAPSHOT_FOLDER}"
+  BASE_PUBLISH_PATH="${TARGET_FOLDER}/${LAST_SNAPSHOT_FOLDER}"
   if [ -n "${TARGET_SUBFOLDER}" ]; then
-    PUBLISH_PATH="./${LAST_SNAPSHOT_FOLDER}/${TARGET_SUBFOLDER}"
-  else    
-    PUBLISH_PATH="./${LAST_SNAPSHOT_FOLDER}"
+    PUBLISH_PATH="${TARGET_FOLDER}/${LAST_SNAPSHOT_FOLDER}/${TARGET_SUBFOLDER}"
+  else
+    PUBLISH_PATH="${TARGET_FOLDER}/${LAST_SNAPSHOT_FOLDER}"
   fi
 
   publish_artifacts
@@ -257,11 +261,11 @@
 
   # Publish to the specific version folder
   echo "::group::Publishing Specific Release Version: ${VERSION}"
-  BASE_PUBLISH_PATH="./${VERSION}"
+  BASE_PUBLISH_PATH="${TARGET_FOLDER}/${VERSION}"
   if [ -n "${TARGET_SUBFOLDER}" ]; then
-    PUBLISH_PATH="./${VERSION}/${TARGET_SUBFOLDER}"
-  else    
-    PUBLISH_PATH="./${VERSION}"
+    PUBLISH_PATH="${TARGET_FOLDER}/${VERSION}/${TARGET_SUBFOLDER}"
+  else
+    PUBLISH_PATH="${TARGET_FOLDER}/${VERSION}"
   fi
   publish_artifacts
   echo "Published release documentation to ${PUBLISH_PATH}"
@@ -271,11 +275,11 @@
   genericVersionFolder="${VERSION%.*}"
   genericVersionFolder="${genericVersionFolder}.x"
   echo "::group::Publishing Generic Release Version: ${genericVersionFolder}"
-  BASE_PUBLISH_PATH="./${genericVersionFolder}"
+  BASE_PUBLISH_PATH="${TARGET_FOLDER}/${genericVersionFolder}"
   if [ -n "${TARGET_SUBFOLDER}" ]; then
-    PUBLISH_PATH="./${genericVersionFolder}/${TARGET_SUBFOLDER}"
+    PUBLISH_PATH="${TARGET_FOLDER}/${genericVersionFolder}/${TARGET_SUBFOLDER}"
   else
-    PUBLISH_PATH="./${genericVersionFolder}"
+    PUBLISH_PATH="${TARGET_FOLDER}/${genericVersionFolder}"
   fi
   publish_artifacts
   echo "Published release documentation to ${genericVersionFolder}"
@@ -285,11 +289,11 @@
   if [[ "$SKIP_RELEASE_FOLDER" == "false" ]]; then
     if is_highest_version "${genericVersionFolder}"; then
       echo "::group::Overwriting ${LAST_RELEASE_FOLDER} with the latest release documentation"
-      BASE_PUBLISH_PATH="./${LAST_RELEASE_FOLDER}"
+      BASE_PUBLISH_PATH="${TARGET_FOLDER}/${LAST_RELEASE_FOLDER}"
       if [ -n "${TARGET_SUBFOLDER}" ]; then
-        PUBLISH_PATH="./${LAST_RELEASE_FOLDER}/${TARGET_SUBFOLDER}"
-      else    
-        PUBLISH_PATH="./${LAST_RELEASE_FOLDER}"
+        PUBLISH_PATH="${TARGET_FOLDER}/${LAST_RELEASE_FOLDER}/${TARGET_SUBFOLDER}"
+      else
+        PUBLISH_PATH="${TARGET_FOLDER}/${LAST_RELEASE_FOLDER}"
       fi
       publish_artifacts
       echo "Published a copy of documentation to ${PUBLISH_PATH}"
diff --git a/tests/src/test/groovy/org/apache/grails/github/DeployGithubPagesSpec.groovy b/tests/src/test/groovy/org/apache/grails/github/DeployGithubPagesSpec.groovy
index f2664a5..bb30bba 100644
--- a/tests/src/test/groovy/org/apache/grails/github/DeployGithubPagesSpec.groovy
+++ b/tests/src/test/groovy/org/apache/grails/github/DeployGithubPagesSpec.groovy
@@ -312,6 +312,62 @@
         action.close()
     }
 
+    def "snapshot - published to different base path without subfolder"() {
+        given:
+        Network net = Network.newNetwork()
+
+        and:
+        GitHubVersion release = new GitHubVersion(version: '7.0.0-RC1', targetBranch: '7.0.x', targetVersion: '7.0.0-SNAPSHOT')
+        GitHubDockerAction action = new GitHubDockerAction('deploy-github-pages', release, new GitHubCliMock())
+
+        GitHubRepoMock gitRepo = new GitHubRepoMock(action.workspacePath, net)
+        gitRepo.init()
+        gitRepo.populateRepository('7.0.0-SNAPSHOT', null, [], getProjectFiles())
+        gitRepo.stageRepositoryForAction('main', false)
+
+        and:
+        def env = getDefaultEnvironment(action, gitRepo)
+        env['GRADLE_PUBLISH_RELEASE'] = 'false' // snapshot
+        env['SOURCE_FOLDER'] = 'docs'
+        env['TARGET_FOLDER'] = 'my/base/path'
+        env['VERSION'] = '7.0.0-SNAPSHOT'
+
+        and:
+        action.createContainer(env, net)
+
+        when:
+        action.runAction()
+
+        then:
+        action.actionExitCode == 0L
+        action.actionLogs
+
+        and: 'gh-pages branch created'
+        action.getActionGroupLogs('Creating documentation branch')
+        gitRepo.branchExists('gh-pages')
+
+        and: 'files published to snapshot'
+        gitRepo.getFileContents('index.html', 'gh-pages') == '<html><body>Welcome to the Grails GitHub Pages</body></html>'
+        gitRepo.getFolders('my/base/path/snapshot', 'gh-pages') == []
+        gitRepo.getFileContents('my/base/path/snapshot/index.html', 'gh-pages') == '<html><body>Welcome to the Grails Documentation</body></html>'
+
+        and: 'main did not change'
+        gitRepo.getFileContents('gradle.properties', 'main') == 'projectVersion=7.0.0-SNAPSHOT'
+
+        and: 'main did not add any folders'
+        gitRepo.getFolders('main') == ['docs']
+
+        and: 'gh-pages added expected folders'
+        gitRepo.getFolders('gh-pages') == ['my']
+        gitRepo.getFolders('my', 'gh-pages') == ['base']
+        gitRepo.getFolders('my/base', 'gh-pages') == ['path']
+
+        cleanup:
+        System.out.println("Container logs:\n${action.actionLogs}" as String)
+        gitRepo?.close()
+        action.close()
+    }
+
     def "snapshot - version is ignored on snapshot"() {
         given:
         Network net = Network.newNetwork()
@@ -427,6 +483,72 @@
         action.close()
     }
 
+    def "release - published to different base path without subfolder"() {
+        given:
+        Network net = Network.newNetwork()
+
+        and:
+        GitHubVersion release = new GitHubVersion(version: '7.0.0-RC1', tagName: 'rel-7.0.0-RC1', targetBranch: '7.0.x', targetVersion: '7.0.0-SNAPSHOT')
+        GitHubDockerAction action = new GitHubDockerAction('deploy-github-pages', release, new GitHubCliMock())
+
+        GitHubRepoMock gitRepo = new GitHubRepoMock(action.workspacePath, net)
+        gitRepo.init()
+        gitRepo.populateRepository('7.0.0-SNAPSHOT', null, [], getProjectFiles())
+        gitRepo.stageRepositoryForAction('main', false)
+
+        and:
+        def env = getDefaultEnvironment(action, gitRepo)
+        env['GRADLE_PUBLISH_RELEASE'] = 'true'
+        env['SKIP_SNAPSHOT_FOLDER'] = 'true' // should be ignored because this is a release
+        env['TARGET_FOLDER'] = 'my/base/path'
+        env['SOURCE_FOLDER'] = 'docs'
+        env['VERSION'] = '7.0.0-RC1'
+
+        and:
+        action.createContainer(env, net)
+
+        when:
+        action.runAction()
+
+        then:
+        action.actionExitCode == 0L
+        action.actionLogs
+
+        and:
+        !action.actionLogs.contains('Snapshot detected and snapshot publishing is disabled. Skipping documentation deployment.')
+
+        and:
+        action.getActionGroupLogs('Publishing Specific Release Version: 7.0.0-RC1')
+        action.getActionGroupLogs('Publishing Generic Release Version: 7.0.x')
+        action.getActionGroupLogs('Overwriting latest with the latest release documentation')
+
+        and:
+        gitRepo.branchExists('gh-pages')
+
+        and:
+        gitRepo.getFolders('gh-pages') == ['my']
+        gitRepo.getFolders('my', 'gh-pages') == ['base']
+        gitRepo.getFolders('my/base', 'gh-pages') == ['path']
+        gitRepo.getFolders('my/base/path', 'gh-pages').sort() == ['7.0.0-RC1', '7.0.x', 'latest']
+        gitRepo.getFileContents('index.html', 'gh-pages') == '<html><body>Welcome to the Grails GitHub Pages</body></html>'
+
+        and:
+        gitRepo.getFileContents('my/base/path/latest/index.html', 'gh-pages') == '<html><body>Welcome to the Grails Documentation</body></html>'
+        gitRepo.getFileContents('my/base/path/7.0.x/index.html', 'gh-pages') == '<html><body>Welcome to the Grails Documentation</body></html>'
+        gitRepo.getFileContents('my/base/path/7.0.0-RC1/index.html', 'gh-pages') == '<html><body>Welcome to the Grails Documentation</body></html>'
+
+        and: 'main did not change'
+        gitRepo.getFileContents('gradle.properties', 'main') == 'projectVersion=7.0.0-SNAPSHOT'
+
+        and: 'main did not add any folders'
+        gitRepo.getFolders('main') == ['docs']
+
+        cleanup:
+        System.out.println("Container logs:\n${action.actionLogs}" as String)
+        gitRepo?.close()
+        action.close()
+    }
+
     def "release - published with subfolder"() {
         given:
         Network net = Network.newNetwork()