Including Git Data in Deploy

This article will go over how to include information from Git, such as branch name or commit hash, into the robot code. This is necessary for using such information in robot code, such as printing out commit hash and branch name when the robot starts.

Note

Git must be in the path for this to work. This should be enabled by default when installing Git.

Deploying Branch Name

This example uses git rev-parse to extract data the name of the current branch. The Git command used for this is:

$ git rev-parse --abbrev-ref HEAD

The --abbrev-ref flag tells Git to use a short version of the name for the current commit that rev-parse is acting on. When HEAD is the most recent commit on a branch, this will return the name of that branch.

Next, create a new task in the build.gradle file that will run the above Git command and write it to a file in the src/main/deploy directory. For example, the following is an example task named writeBranchName that will write the branch name to a file named branch.txt.

tasks.register("writeBranchName") {
   // Define an output stream to write to instead of terminal
   def stdout = new ByteArrayOutputStream()

   // Execute the git command
   exec {
      commandLine "git", "rev-parse", "--abbrev-ref", "HEAD"
      // Write to the output stream instead of terminal
      standardOutput = stdout
   }

   // Parse the output into a string
   def branch = stdout.toString().trim()

   // Create a new file
   new File(
      // Join project directory and deploy directory
      projectDir.toString() + "/src/main/deploy",
      // File name to write to
      "branch.txt"
   ).text = branch // Set the contents of the file to the variable branch
}

This registers a Gradle task that uses the above Git command, saves the output to a variable, and then writes it to a file. Since it was written to the src/main/deploy directory, it will be included in the jar file deployed to the robot and accessible in code.

The next step is to make the deploy task depend on the task you created, so that it will automatically run before the code is deployed. This example uses the task name writeBranchName from the previous example, but it should be replaced with the name of the task in your build.gradle.

deploy.targets.roborio.artifacts.frcStaticFileDeploy.dependsOn(writeBranchName)

Deploying Commit Hash

Similar to the previous example, git rev-parse will be used to parse the current commit hash. The Git command used for this is:

$ git rev-parse --short HEAD

Similar to the previous Git command, rev-parse is used to find information about the commit at HEAD. However, instead of using --abbrev-ref to find the branch name associated with that commit, --short is used to find the 7-character commit hash.

Note

If you wish to use the full commit hash instead of the 7-character version, you can leave out the --short flag.

Next is to create a task in build.gradle that runs this command and writes the output to a file. This is largely the same as the first example, except the task is named writeCommitHash, the new Git command is used, and it is written to commit.txt instead of branch.txt.

tasks.register("writeCommitHash") {
   def stdout = new ByteArrayOutputStream()

   exec {
     commandLine "git", "rev-parse", "--short", "HEAD"
     standardOutput = stdout
   }

   def commitHash = stdout.toString().trim()

   new File(
      projectDir.toString() + "/src/main/deploy",
      "commit.txt"
   ).text = commitHash
}

deploy.targets.roborio.artifacts.frcStaticFileDeploy.dependsOn(writeCommitHash)

Ignoring Generated Files with Git

Since these files include data that is already tracked by Git and are regenerated every time code is deployed, it is recommended to not track these changes with Git by using the gitignore file. This file should exist by default in any project generated by the WPILib VS Code extension. Below is an example that continues to use the branch.txt and commit.txt file names:

src/main/deploy/branch.txt
src/main/deploy/commit.txt
...

Using Deployed Files

In order to access files that were written to the deploy directory in code, you have to use the getDeployDirectory() method of the Filesystem class in Java, or the GetDeployDirectory() function of the frc::filesystem namespace in C++. Below is an example of opening both files from the previous examples:

Note

Opening and reading the files is slow and should not be performed during any periodic methods. Since the file will only change on deploy, it only needs to be read once.

File deployDir = Filesystem.getDeployDirectory();
File branchFile = new File(deployDir, "branch.txt");
File commitFile = new File(deployDir, "commit.txt");

For more information on how to interact with the file objects, see the documentation of the File class.