Skip to content

Commit

Permalink
feat(action): add functions for handling git describe
Browse files Browse the repository at this point in the history
- the motivations behind this:
- coreboot likes to embed its source version into the compiled binary
- coreboot does that by calling 'git describe ...'
- however with firmware-action we can assume people will include
  coreboot as git submodule, and thus when compiling coreboot in
  container the git commands will fail because of missing .git directory
- to fix this we will run manually the 'git describe' command and then
  pass it in form of env variable into the container

Signed-off-by: AtomicFS <[email protected]>
  • Loading branch information
AtomicFS committed Jan 8, 2025
1 parent 0f0a9a6 commit 3599c9f
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 0 deletions.
72 changes: 72 additions & 0 deletions action/filesystem/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: MIT

// Package filesystem / git implements git-related commands
package filesystem

import (
"fmt"
"log/slog"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
)

// gitRun is generic function to execute any git command in sub-directory
func gitRun(subdir string, command []string) (string, error) {
// subdir is relative to current working directory

// Get current working directory
pwd, err := os.Getwd()
if err != nil {
return "", err
}

// Change current working directory into the repository / submodule
defer os.Chdir(pwd) // nolint:errcheck
subdirPath := filepath.Join(pwd, subdir)
err = os.Chdir(subdirPath)
if err != nil {
slog.Error(
fmt.Sprintf("Failed to change current working directory to '%s'", subdirPath),
slog.Any("error", err),
)
return "", err
}

// Run git describe
cmd := exec.Command(command[0], command[1:]...)
describe, err := cmd.CombinedOutput()
if err != nil {
slog.Error(
fmt.Sprintf("Failed to run git command in '%s'", subdirPath),
slog.Any("error", err),
)
return "", err
}

return string(describe), nil
}

// GitDescribeCoreboot is coreboot-specific git describe command
func GitDescribeCoreboot(repoPath string) (string, error) {
describe, err := gitRun(repoPath, []string{"git", "describe", "--abbrev=12", "--dirty", "--always"})
if err != nil {
return "", err
}

// Remove trailing newline
result := strings.TrimSpace(describe)

// Check validity of the retuned string
pattern := regexp.MustCompile(`[\d\w]{13}(\-dirty)?`)
valid := pattern.MatchString(result)
if !valid {
slog.Warn(
fmt.Sprintf("Output of 'git describe' for '%s' seems to be invalid, output is: '%s'", repoPath, result),
)
}

return result, err
}
68 changes: 68 additions & 0 deletions action/filesystem/git_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// SPDX-License-Identifier: MIT
package filesystem

import (
"os"
"path/filepath"
"testing"

"github.com/go-git/go-git/v5"
"github.com/stretchr/testify/assert"
)

func gitRepoPrepare(t *testing.T, tmpDir string) {
// Create empty git repository
repo, err := git.PlainInit(tmpDir, false)
assert.NoError(t, err)

// Create a worktree to interact with the repo
worktree, err := repo.Worktree()
assert.NoError(t, err)

// Create a simple text file for testing
filename := "README.md"
pathFile := filepath.Join(tmpDir, filename)
err = os.WriteFile(pathFile, []byte{}, 0o666)
assert.NoError(t, err)

// Commit the file (must be relative path)
_, err = worktree.Add(filename)
assert.NoError(t, err)

commitOpts := &git.CommitOptions{}
_, err = worktree.Commit("Initial commit", commitOpts)
assert.NoError(t, err)
}

func TestGitRun(t *testing.T) {
tmpDir := t.TempDir()

pwd, err := os.Getwd()
assert.NoError(t, err)
defer os.Chdir(pwd) // nolint:errcheck
err = os.Chdir(tmpDir)
assert.NoError(t, err)

gitRepoPrepare(t, tmpDir)

// Test git status
stdout, err := gitRun("./", []string{"git", "status"})
assert.NoError(t, err)
assert.Equal(t, stdout, "On branch master\nnothing to commit, working tree clean\n")
}

func TestGitDescribeCoreboot(t *testing.T) {
tmpDir := t.TempDir()

pwd, err := os.Getwd()
assert.NoError(t, err)
defer os.Chdir(pwd) // nolint:errcheck
err = os.Chdir(tmpDir)
assert.NoError(t, err)

gitRepoPrepare(t, tmpDir)

// Test git status
_, err = GitDescribeCoreboot("./")
assert.NoError(t, err)
}

0 comments on commit 3599c9f

Please sign in to comment.