How do I access my .git directory from within my app?

I want to be able to access the commit hash and timestamp of the current state of my project, but I don’t see a .git repository when I SSH in to my application. How can I access the information stored in .git?

Platform.sh doesn’t provide direct access to your .git repository, but there are still a few methods you can use to access that information from your application.

Get the commit hash of your current work tree

Although the commit hash of the state of your project isn’t available to your application directly, it is still possible to figure it out using the PLATFORM_TREE_ID environment variable that is provided to your application and our CLI tool.

WARNING: This method is provided only as a proof of concept. Please be sure to thoroughly test your implementation of this method before putting it into production.

Configure dependencies

First, you’ll need to configure an environment variable to pass your API token to the build process. In your project settings (not the settings for any individual environment), add an environment variable to contain your API token:

Set the name to env:PLATFORMSH_CLI_TOKEN, mark it as sensitive, and indicate that you want it to be available during the build process but not the runtime.

This proof-of-concept method has two dependencies: the Platform.sh CLI and the jq command line tool for parsing JSON objects. We can install both in the build hook by adding these lines:

curl -sS https://platform.sh/cli/installer | php
wget -q https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -O jq
chmod +x jq # Make jq executable

Talking with the API

Create a new file called get-commit.sh in the root directory of your application, and paste in the script below. Make sure to make the script executable with chmod +x get-commit.sh.

#!/usr/bin/env bash

${PLATFORM_APP_DIR}/.platformsh/bin/platform p:curl -X GET activities | \
${PLATFORM_APP_DIR}/jq -r \
    --arg tree ${PLATFORM_TREE_ID:0:7} \
    --arg app ${PLATFORM_APPLICATION_NAME} \
    '.[] |
        select(.type == "environment.push") |
        select(.log | (contains("tree: " + $tree))) |
        [0] | .payload.commits | .[0].sha
    '

The above script makes a call to the activities API endpoint for the project in which this script is being run and extracts a commit hash from the results. Let’s break it down:

  • .[] | – This command iterates over the array of results and pipes each object to the next command.

  • select(.type == "environment.push") | – This selects the subset of activity entries that are Git push events.

  • select(.log | (contains("tree: " + $tree))) | – This takes the log key from each event entry and checks to see if it has the string tree: $tree contained within, where $tree is the first seven characters of $PLATFORM_TREE_ID. The

  • [0] | .payload.commits | .[0].sha – This line takes the first matching event and returns the SHA hash of the most recent commit.

Final build hook

Call get-commit.sh from your build hook and output the result to a file called .commit, like so:

hooks:
    build: |
      # Other commands omitted for space

      # Dependencies for getting the current commit
      curl -sS https://platform.sh/cli/installer | php
      wget -q https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -O jq

      # Make the script executable
      chmod +x jq

      # Output the commit hash to a file
      ./get-commit.sh > .commit

      # If you don't need `jq` for anything else, you can remove it
      rm jq

This method should work reliably because the .commit file is only updated during the build hook. Thus, if you have multiple apps in one project, only apps that have code changes with each commit will be rebuilt, making the contents of the .commit file permanently associated with the correct commit.

Without dependencies

As mentioned above, this example is only a proof-of-concept. It is also possible to query the Platform.sh API directly without the CLI tool, and you can process the JSON results with any tool or language that you prefer.

Adding a .git repo for other tools to use

Some tools, such as a static site generator like Hugo, can parse the information contained within the .git directory and use it to determine when pages were last updated, who has edited a page, etc. For this use case, you’ll need more than just the commit hash.

If you want to have access to that information in your application, you can clone the repository that is being used to build the application and extract the .git repo from there.

In your .platform.app.yaml file:

hooks:
    build: |
      # Optionally, the contents from the build hook in the previous section
      # . . .

      # Clone the repository for the current project
      git clone git@github.com:YOUR-NAME/YOUR-REPOSITORY.git .repo

      # Optionally, set the working state of the repository to the current commit
      cd .repo
      git reset --hard $(cat ${PLATFORM_APP_DIR}/.commit)
      cd ..

      # Move the .git repo into the root directory of the app, and delete the old working tree
      mv .repo/.git .
      rm -rf .repo

Now any tools you want to use can process this repository as if it were any other working tree containing a .git directory.