diff --git a/.github/.DS_Store b/.github/.DS_Store new file mode 100644 index 0000000..095c84d Binary files /dev/null and b/.github/.DS_Store differ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..eeb2b35 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,101 @@ +name: dotCMS sync + +on: [push] + +jobs: + sync-with-dotcms: + runs-on: ubuntu-latest + env: + # Global environment expected by dotCMS CLI + # This is how we instruct the cli the target server + DOT_API_URL: ${{ vars.DOT_API_URL }} + # This is how we instruct the cli the target folder in the repo + # By default it must be the root of the repo this allows setting up a different folder on top of the root + DOT_REPO_BASE_PATH: ${{ vars.DOT_REPO_BASE_PATH }} + # This is how we instruct the cli to create the workspace if it does not exist + DOT_CREATE_WORKSPACE: ${{ vars.DOT_CREATE_WORKSPACE || 'true' }} + # This is the CLI version to use, but we can always override this value + DOT_CLI_JAR_DOWNLOAD_URL: ${{ vars.DOT_CLI_JAR_DOWNLOAD_URL || 'https://repo.dotcms.com/artifactory/libs-snapshot-local/com/dotcms/dotcms-cli/1.0.0-SNAPSHOT/dotcms-cli-1.0.0-20231002.205953-1.jar' }} + # In case we want to force the download of the CLI jar + DOT_FORCE_DOWNLOAD: ${{ vars.DOT_FORCE_DOWNLOAD || 'false' }} + steps: + - name: Checkout + uses: actions/checkout@v4 + id: checkout + with: + fetch-depth: 0 + + - name: Load .env file + uses: aarcangeli/load-dotenv@v1.0.0 + with: + if-file-not-found: 'warn' + + - name: Print env vars + run: | + echo "$GITHUB_ENV" + + - name: Get changes + run: | + git diff --name-only ${{ github.event.before }} ${{ github.event.after }} > changed_files.txt + + - name: List changed files + run: | + while IFS= read -r line + do + echo "\"$line\" was changed" + done < changed_files.txt + + - name: Github Event Context properties + run: | + echo "Event: ${{ github.event }}" + echo "Event Name: ${{ github.event_name }}" + echo "Repository: ${{ github.repository }}" + echo "Commit SHA: ${{ github.sha }}" + echo "Commit Ref: ${{ github.ref }}" + echo "Head Ref: ${{ github.head_ref }}" + echo "Base Ref: ${{ github.base_ref }}" + echo "Triggered by: ${{ github.actor }}" + echo "Workflow: ${{ github.workflow }}" + echo "PR: ${{ github.pull_request }}" + echo "Workspace: ${{ github.workspace }}" + + - name: Create workspace if not exists + id: dot-workspace + run: | + if [ ${{ env.DOT_CREATE_WORKSPACE }} = true ]; then + echo "Creating workspace ::: " + chmod +x ./.github/workflows/scripts/workspace.sh + source ./.github/workflows/scripts/workspace.sh + workspace_updated=$(create_workspace "${{github.workspace}}${{env.DOT_REPO_BASE_PATH}}" ) + echo "workspace-updated=$workspace_updated" >> "$GITHUB_OUTPUT" + fi + shell: bash + + # This step requires permission to push to the repo + # you need to grant read/write permission for workflows in the repo settings + - name: Persist updated workspace + run: | + saveChanges="${{ steps.dot-workspace.outputs.workspace-updated }}" + if [ -n "${saveChanges}" ]; then + git config user.name "${{ secrets.CI_MACHINE_USER }}" + git config user.email "dotCMS-Machine-User@dotcms.com" + git add . + git commit -m "pushing workspace changes" + git push + echo "Workspace has been updated." + fi + + - name: Run dotCMS CLI + id: dot-push + run: | + chmod +x ./.github/workflows/scripts/run-push.sh + source ./.github/workflows/scripts/run-push.sh + install_cli "${{env.DOT_CLI_JAR_DOWNLOAD_URL}}" "${{env.DOT_FORCE_DOWNLOAD}}" + run_cli_push "${{github.workspace}}${{env.DOT_REPO_BASE_PATH}}" "${{ secrets.DOT_TOKEN }}" "${{ env.DOT_CLI_OPTS }}" + echo "exit-code=$exit_code" >> "$GITHUB_OUTPUT" + print_log + if [ $exit_code -ne 0 ]; then + echo "Error running dotCMS CLI" + exit 1 + fi + shell: bash diff --git a/.github/workflows/scripts/run-push.sh b/.github/workflows/scripts/run-push.sh new file mode 100644 index 0000000..c2e8246 --- /dev/null +++ b/.github/workflows/scripts/run-push.sh @@ -0,0 +1,119 @@ +#!/bin/sh + + DOT_CLI_JAR="dot-cli.jar" + DOT_CLI_HOME="/tmp/dot-cli/" + DOT_SERVICE_YML="dot-service.yml" + RUN_JAVA_VERSION=1.3.8 + +SERVICES_FILE_CONTENT=" +- name: \"default\" + active: true + url: \"$DOT_API_URL\" +" + +_make_home(){ + if [ ! -d "$DOT_CLI_HOME" ]; then + mkdir $DOT_CLI_HOME + fi +} + +_get_CLI(){ + + cli_release_download_url=$1 + force_download=$2 + + cliJar=${DOT_CLI_HOME}${DOT_CLI_JAR} + if [ -f $cliJar ] && ! [ "$force_download" = true ] ; then + echo "dot-CLI already exists, skipping download" + return + fi + + curl "$cli_release_download_url" -L -o ${DOT_CLI_HOME}${DOT_CLI_JAR} + chmod 777 "${DOT_CLI_HOME}${DOT_CLI_JAR}" + + #Check the size of the file + file="${DOT_CLI_HOME}${DOT_CLI_JAR}" && \ + actual_size=$(wc -c <"$file"); + + if [ "$actual_size" -lt 1000000 ]; then + echo "The file is too small to be the CLI, please check the version and try again" + exit 1 + fi +} + +_get_run_java_script(){ + force_download=$1 + runJava=${DOT_CLI_HOME}run-java.sh + if [ -f "$runJava" ] && ! [ "$force_download" = true ] ; then + echo "run-java.sh already exists, skipping download" + return + fi + curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/"${RUN_JAVA_VERSION}"/run-java-sh-"${RUN_JAVA_VERSION}"-sh.sh -o "${DOT_CLI_HOME}"run-java.sh + chmod 777 ${DOT_CLI_HOME}run-java.sh +} + +_setup_CLI(){ + #Lets create the services file dot-service.yml + #the services yml is used to store the server configurations or profiles if you Will + DOT_SERVICES_HOME=$HOME/.dotcms/ + SERVICE_FILE=$DOT_SERVICES_HOME$DOT_SERVICE_YML + # All we need is a file with an active profile that matches the server we want to connect to in this case we are using default + # If the directory does not exist we create it + if [ ! -d "$DOT_SERVICES_HOME" ]; then + mkdir "$DOT_SERVICES_HOME" + else + # If the directory exists we remove it as we could be updating the server url + rm -rf "$DOT_SERVICES_HOME" + mkdir "$DOT_SERVICES_HOME" + fi + # Now generate the file + echo "$SERVICES_FILE_CONTENT" >> "$SERVICE_FILE"; + + export QUARKUS_LOG_FILE_PATH=$DOT_CLI_HOME"dotcms-cli.log" +} + +print_log(){ + echo "Quarkus log file contents:" + cat "$QUARKUS_LOG_FILE_PATH" +} + +_run_cli_push(){ + workspace_path=$1 + token=$2 + push_opts=$3 + + #These environment vars are expected by the start-up script + export JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" + # This is a relative path to the run-java.sh file, both the jar and script are expected to live in the same folder + export JAVA_APP_JAR="$DOT_CLI_JAR" + # This is the name of the process that will be used to identify the process in the container + export JAVA_APP_NAME="dotcms-cli" + # Log file + export QUARKUS_LOG_FILE_PATH="$DOT_CLI_HOME"dotcms-cli.log + cmd="bash /tmp/dot-cli/run-java.sh push $workspace_path $push_opts --token=$token" + eval "$cmd" + export exit_code=$? + echo $exit_code +} + +install_cli(){ + cli_release_download_url=$1 + force_download=$2 + + _make_home + _get_CLI "$cli_release_download_url" "$force_download" + _get_run_java_script "$force_download" + _setup_CLI +} + +run_cli_push(){ + workspace_path=$1 + token=$2 + push_opts=$3 + + echo "PUSH OPTS:" + echo "$push_opts" + + return_code=$(_run_cli_push "$workspace_path" "$token" "$push_opts") + echo "$return_code" +} diff --git a/.github/workflows/scripts/workspace.sh b/.github/workflows/scripts/workspace.sh new file mode 100644 index 0000000..54d05f9 --- /dev/null +++ b/.github/workflows/scripts/workspace.sh @@ -0,0 +1,132 @@ +#!/bin/sh + +DOT_WORKSPACE_YML=".dot-workspace.yml" +FILES_NAME_SPACE="/files/" +CONTENT_TYPES_NAME_SPACE="/content-types/" +LANGUAGES_NAME_SPACE="/languages/" +SITES_NAME_SPACE="/sites/" + +## This file forces git to keep empty folders +PLACEHOLDER_FILE=.dot-ignore +## We need an empty file to create the folders cause git does not track empty folders +PLACEHOLDER_FILE_CONTENT='#placeholder file +' +WORKSPACE_FILE_CONTENT='name: default +version: 1.0.0 +description: "DO NOT ERASE ME !!! I am a marker file required by dotCMS CLI."' + +## +## +_normalize() { + in=$1 + normalized=$(echo "$in" | sed -E 's#/+#/#g') + echo "$normalized" +} + +## Creates the .dot_workspace yml file expected by the CLI to be able to work +## expects a base path to work with +_workspace_file(){ + BASE_PATH=$1 + #echo "$BASE_PATH" + WORKSPACE_FILE=$BASE_PATH/$DOT_WORKSPACE_YML + #echo Workspace-file :: "$WORKSPACE_FILE" + WORKSPACE_FILE=$(_normalize "$WORKSPACE_FILE") + #echo normalized :: "$WORKSPACE_FILE" + if [ ! -f "$WORKSPACE_FILE" ]; then + #echo "writing to file ::" + echo "$WORKSPACE_FILE_CONTENT" >> "$WORKSPACE_FILE"; + #echo "writing to file done!" + echo "$WORKSPACE_FILE"; + fi +} + +## Creates the files workspace path including live, working and language directories +## expects a base path to work with +_files_path(){ + BASE_PATH=$1 + FILES_PATH=$BASE_PATH/$FILES_NAME_SPACE + FILES_PATH=$(_normalize "$FILES_PATH") + + #echo "Files path: $FILES_PATH" + if [ ! -d "$FILES_PATH" ]; then + #echo "Creating files path: $FILES_PATH"; + mkdir -p "$FILES_PATH"; + + WORKING_EN=$(_normalize "$FILES_PATH"/working/en-us/ ) + #echo "Working en-us path: $WORKING_EN"; + mkdir -p "$WORKING_EN"; + echo "$PLACEHOLDER_FILE_CONTENT" >> "$WORKING_EN""$PLACEHOLDER_FILE" + + LIVE_EN=$(_normalize "$FILES_PATH"/live/en-us/ ) + #echo "Live en-us path: $LIVE_EN"; + mkdir -p "$LIVE_EN"; + echo "$PLACEHOLDER_FILE_CONTENT" >> "$LIVE_EN""$PLACEHOLDER_FILE" + + echo "$FILES_PATH" + fi +} + +## Creates the content_types workspace path +## expects a base path to work with +_content_types_path(){ + BASE_PATH=$1 + CONTENT_TYPES_PATH=$BASE_PATH/$CONTENT_TYPES_NAME_SPACE + CONTENT_TYPES_PATH=$(_normalize "$CONTENT_TYPES_PATH") + #echo "Content types path: $CONTENT_TYPES_PATH" + if [ ! -d "$CONTENT_TYPES_PATH" ]; then + #echo "Creating content types path: $CONTENT_TYPES_PATH"; + mkdir -p "$CONTENT_TYPES_PATH"; + echo "$PLACEHOLDER_FILE_CONTENT" >> "$CONTENT_TYPES_PATH""$PLACEHOLDER_FILE" + echo "$CONTENT_TYPES_PATH" + fi +} + +## Creates the languages workspace path +## expects a base path to work with +_languages_path(){ + BASE_PATH=$1 + LANGUAGE_PATH=$BASE_PATH/$LANGUAGES_NAME_SPACE + LANGUAGE_PATH=$(_normalize "$LANGUAGE_PATH") + #echo "Languages path: $LANGUAGE_PATH" + if [ ! -d "$LANGUAGE_PATH" ]; then + mkdir -p "$LANGUAGE_PATH"; + echo "$PLACEHOLDER_FILE_CONTENT" >> "$LANGUAGE_PATH""$PLACEHOLDER_FILE" + echo "$LANGUAGE_PATH" + fi +} + +## Creates the sites workspace path +## expects a base path to work with +_sites_path(){ + BASE_PATH=$1 + SITES_PATH=$BASE_PATH/$SITES_NAME_SPACE + SITES_PATH=$(_normalize "$SITES_PATH") + #echo "Sites path: $SITES_PATH" + if [ ! -d "$SITES_PATH" ]; then + #echo "Creating sites path: $SITES_PATH"; + mkdir -p "$SITES_PATH"; + echo "$PLACEHOLDER_FILE_CONTENT" >> "$SITES_PATH""$PLACEHOLDER_FILE" + echo "$SITES_PATH" + fi +} + +## This function serves as the entry point the script +## it expects a base path to work with +create_workspace(){ + basePath="$1" + basePath=$(_normalize "$basePath") + workspace_file=$(_workspace_file "$basePath") + files=$(_files_path "$basePath") + contentTypes=$(_content_types_path "$basePath") + languages=$(_languages_path "$basePath") + sites=$(_sites_path "$basePath") + + if [ -n "$workspace_file" ] || [ -n "$files" ] || [ -n "$contentTypes" ] || [ -n "$languages" ] || [ -n "$sites" ]; then + echo "Workspace updated" + fi + +} + + + +