Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RESEARCH: Evaluate what is required to send from the GHA to the entrypoint.sh #25821

Closed
Tracked by #24354
nollymar opened this issue Aug 18, 2023 · 1 comment · Fixed by #26031
Closed
Tracked by #24354

RESEARCH: Evaluate what is required to send from the GHA to the entrypoint.sh #25821

nollymar opened this issue Aug 18, 2023 · 1 comment · Fixed by #26031

Comments

@nollymar
Copy link
Contributor

nollymar commented Aug 18, 2023

Parent Issue

#24354

The main idea is understand how a docker container action works and what relevant information we get when pushing files to a repo.

Expected result:
Identify what input will be sent to the action and to the entrypoint.sh. Having this information, define what info will receive the entrypoint.sh and what logic this script will have in order to invoke a "super push" CLI command.

@fabrizzio-dotCMS
Copy link
Contributor

fabrizzio-dotCMS commented Sep 12, 2023

As a learning exercise, I built a workflow action + a docker container action aiming to integrate a GitHub repo and our CLI to pull or pull content from a dotCMS instance.
The repository has the following structure
repo
+- .githithub. (Contains the workflow definition)
+- actions (Our Custom private action)
+- contents (Represents a customer repo)

For every Git push event, the workflow fires the action
The action is composed of a yml definition file, a Dokerfile that builds the CLI, and an entrypoint.sh script that passes down the parameters and runs the CLI

in the action yml file we declare and capture the params expected by our cli command

for this particular exercise I chose to do a Content-Type pull

The cli command looks like this
'ct pull FileAsset --workspace /github/workspace/'

for which the declared params on the action are:

runs:
  using: 'docker'
  image: 'Dockerfile'
  args:     
    - ${{ inputs.command }} # match ct
    - ${{ inputs.sub-command }}  # match pull 
    - ${{ inputs.default-action-arg }} # FileAsset
    - ${{ inputs.option }} # --workspace 
    - ${{ inputs.option-value }} # the workspace value
    - ${{ inputs.option-verbose }} # the verbose option

Each one entry gets mapped into a param accesible like
$1, $2, $3 ... from the entrypoint script

Then we have the Dockerfile

  • which I used to collect and include all the artifacts required by the cli to work
  • the cli jar itself
  • the "entrypoint.sh"
  • a run-java script which is the defacto script used to launch jars from containerized environments.
  • a dot-service.yml which is the placeholder for an access token that needs to be injected
  • Additionally, we need to tell the CLI to use the target server (demo in this case)
    We do this by overriding the property named
    dotcms.client.servers.default see in this case we do it by creating an environment var ENV DOTCMS_CLIENT_SERVERS_DEFAULT=https://demo.dotcms.com/api Notice that The suffix value used to create the environment value must match the name on dot-service.yml file in this case we are using default
  • and last but not least we need to define another environment variable that will tell the cli where the log file will live. and that is done like this
ENV DOT_CLI_HOME=/dot-cli/
ENV QUARKUS_LOG_FILE_PATH=${DOT_CLI_HOME}dotcms-cli.log

The Dockerfile looks as follows:

#image base
FROM openjdk:11

ARG JAVA_PACKAGE=openjdk-11-jre-headless
#Java Version we're running on 
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
#Our CLI version 
ARG RUN_DOT_CLI_VERSION='1.0.0-SNAPSHOT'

#We need to know user home as our dot-services.yml lives here 
ENV USER_HOME=/root/
ENV DOT_SERVICES_HOME=${USER_HOME}.dotcms/

#This is our cli home 
ENV DOT_CLI_HOME=/dot-cli/
ENV QUARKUS_LOG_FILE_PATH=${DOT_CLI_HOME}dotcms-cli.log
#Our cli name
ENV DOT_CLI=cli-${RUN_DOT_CLI_VERSION}-runner.jar

ENV DOT_CLI_JAR = "${DOT_CLI_HOME}${DOT_CLI}"

RUN mkdir -p ${DOT_CLI_HOME}
RUN chmod 777 ${DOT_CLI_HOME}

#Let's copy our inputs into our cli home
COPY ${DOT_CLI} ${DOT_CLI_HOME}
COPY entrypoint.sh ${DOT_CLI_HOME}

#now move the file into the dotcms folder located under the user home folder
COPY dot-service.yml ${DOT_SERVICES_HOME}

RUN echo "DOT_CLI_HOME: ${DOT_CLI_HOME}"

RUN apt-get update && \
    apt-get install -y curl && \
    apt-get clean;

#This script is used to run the jar 
RUN 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
RUN chmod 777 ${DOT_CLI_HOME}run-java.sh

ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
ENV JAVA_APP_JAR="${DOT_CLI}"
ENV JAVA_APP_NAME="dotcms-cli"

#Tell the CLI to use the demo server
#The suffix value used to create the environment value must match the name on the dot-service.yml file in this case we are using default
#dotcms.client.servers.default=https://demo.dotcms.com/api
ENV DOTCMS_CLIENT_SERVERS_DEFAULT=https://demo.dotcms.com/api

#The following are here to enable debug mode
#ENV JAVA_DEBUG="y"
#ENV JAVA_DEBUG_SUSPEND="y"
#ENV JAVA_DEBUG_PORT="5005"
#EXPOSE 5005

#Code file to execute when the docker container starts up (`entrypoint.sh`)
ENTRYPOINT ["/dot-cli/entrypoint.sh"]

The entrypoint file looks as follows:

#!/bin/sh
  
  ls /dot-cli

  echo "Proof that we can access the repo from within the script."
  cat /github/workspace/README.md
  
  #Use this in case we want to do the token injection into the dot-service file
  #Replace the token with the value passed in the docker workflow action
  #sed -i -e  "s/plchldr/$tkn/g" "${DOT_SERVICES_HOME}dot-service.yml"
 
 #invoke the script that runs our jar and pass the array of actual params we passed from the action
 #This script will auto-discover any jar located in the current working directory
 #So since we moved both the script and the jar to the same folder it'll find it quite easily
  var=$(bash /dot-cli/run-java.sh "$@" )  
 #Capture the execution output
  echo "var: $var"
 #Capture the cli exit code
  echo "exit code: $?"
 #and finally let's have a look at the log file
  cat "${QUARKUS_LOG_FILE_PATH}"

 #Now lets have a look at the GitHub workspace where the repository is checkout  
  echo "Repository after cli run ::: " 
 #This allows us to verify our files were downloaded 
  ls /github/workspace/contents/
  #and we're done
  echo "done!"

Other findings
The files downloaded into /github/workspace/contents/ aren't permanent
Do NOT expect these files to be part of the repo. The contents of this directory might be identical to the contents of the repo but they are separate contexts. In order to persist these files an additional step must be configured in the workflow

like this:

- name: Trigger dot-cli
        uses: ./actions/dot-cli
        id: dot-cli
        with:           
           command: 'ct'
           sub-command: 'pull'
           default-action-arg: 'FileAsset'
           option: '--workspace'
           option-value: '/github/workspace/contents/' 
           option-verbose: '--verbose'     

      - name: Commit and push
        run: |
          git config user.name "GitHub Actions"
          git config user.email "[email protected]"
          git add $GITHUB_WORKSPACE/contents
          git commit -m "pushing changes"
          git push

Once the dot-cli is executed we need to commit the generated files into the repo
Also, and this is very important the repo needs to count with read-write permissions
These are granted in the repo settings area.

and finally

I never really got to use this but I think this code is extremely util as it allows me to know exactly
What is going on with my repo. It basically configures a standard action checks out the repo and prints the event info behind push and pull.

The following is part of the workflow action

- name: Checkout 
        uses: actions/checkout@v3      
        id: checkout
        with:
           fetch-depth: 0

      - name: Get changes
        id: changed-files
        run: |
          echo "changed_files=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} | xargs)" >> $GITHUB_OUTPUT

      - name: List changed files
        run: |
            for file in ${{ steps.changed-files.outputs.changed_files }}; do
                echo "$file was changed"
            done    

      - name: Get 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 }}"

Here's a quick guide I was pointed to to get started with docker container actions
Here's the repo with all the files listed above

@fabrizzio-dotCMS fabrizzio-dotCMS removed their assignment Sep 12, 2023
@fabrizzio-dotCMS fabrizzio-dotCMS moved this from In Progress to Done in dotCMS - Product Planning Sep 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants