Skip to content
New issue

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

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

Already on GitHub? # to your account

feat: added support for dirty files #368

Merged
merged 11 commits into from
Sep 18, 2023
12 changes: 12 additions & 0 deletions docs/faq/gitdirty.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,15 @@ Add or modify an existing `.gitignore` file to ignore the offending files listed

- Ensure no tracked files are unexpectedly modified
- Prevent the creation of temporary files. If this isn't possible, you can fall back to using a `.gitignore` file.

### use includeArtifacts

Defines a list of files that uplift will ignore when checking the status of the current repository. If a change is detected that is not defined in this list, uplift will assume its default behaviour and fail due to the repository being in a dirty state.

An example usecase is if a file has been generated as part of your release e.g. software bill of materials which you wish to include in your versioning.

```yaml
includeArtifacts:
- file.txt
- path/to/file.txt
```
9 changes: 9 additions & 0 deletions docs/reference/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,15 @@ git:
- option: ci.variable="MAX_RETRIES=10"
skipTag: true
skipBranch: false

# A list of case sensitive files that will be committed to the repo when the
# release is created. Typically these files are managed as part of the
# release process e.g. generated by `hooks`. This allows additional
# information to be included in a release such as a
# Software Bill Of Materials (SBOM) that is created by an external tool.
includeArtifacts:
- file.txt
- path/to/file.txt
```

## gitea
Expand Down
8 changes: 8 additions & 0 deletions docs/static/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@
},
"type": "array",
"minItems": 1
},
"includeArtifacts": {
"items": {
"$comment": "https://upliftci.dev/reference/config#git",
"description": "Defines a list of files that uplift will ignore when checking the status of the current repository. If a change is detected that is not defined in this list, uplift will assume its default behaviour and fail due to the repository being in a dirty state"
},
"type": "array",
"minItems": 1
}
},
"type": "object",
Expand Down
7 changes: 4 additions & 3 deletions internal/config/uplift.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ type Changelog struct {

// Git defines configuration for how uplift interacts with git
type Git struct {
IgnoreDetached bool `yaml:"ignoreDetached"`
IgnoreShallow bool `yaml:"ignoreShallow"`
PushOptions []GitPushOption `yaml:"pushOptions" validate:"dive"`
IgnoreDetached bool `yaml:"ignoreDetached"`
IgnoreShallow bool `yaml:"ignoreShallow"`
PushOptions []GitPushOption `yaml:"pushOptions" validate:"dive"`
IncludeArtifacts []string `yaml:"includeArtifacts" validate:"omitempty,dive,min=1,file"`
}

// GitPushOption provides a way of supplying additional options to
Expand Down
11 changes: 11 additions & 0 deletions internal/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Context struct {
CommitDetails git.CommitDetails
Config config.Uplift
CurrentVersion semver.Version
IncludeArtifacts []string
DryRun bool
Debug bool
FetchTags bool
Expand Down Expand Up @@ -107,5 +108,15 @@ func New(cfg config.Uplift, out io.Writer) *Context {
SCM: SCM{
Provider: Unrecognised,
},
IncludeArtifacts: IncludeArtifacts(cfg),
}
}

// For nil safe object getting
func IncludeArtifacts(c config.Uplift) []string {
if c.Git == nil {
return nil
}

return c.Git.IncludeArtifacts
}
24 changes: 17 additions & 7 deletions internal/task/gitcheck/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ SOFTWARE.
package gitcheck

import (
"strings"

"github.com/apex/log"
"github.com/gembaadvantage/uplift/internal/context"
)
Expand Down Expand Up @@ -57,13 +55,16 @@ func (t Task) Run(ctx *context.Context) error {
}

if len(status) > 0 {
// Convert status into string friendly output
out := make([]string, 0, len(status))
for _, s := range status {
out = append(out, s.String())

if len(ctx.IncludeArtifacts) == 0 {
return ErrDirty{status}
}

return ErrDirty{status: strings.Join(out, "\n")}
for _, sts := range status {
if !stringInSlice(sts.Path, ctx.IncludeArtifacts) {
return ErrDirty{status}
}
}
}

log.Debug("checking for detached head")
Expand All @@ -86,3 +87,12 @@ func (t Task) Run(ctx *context.Context) error {

return nil
}

func stringInSlice(stringToFind string, listOfStrings []string) bool {
for _, value := range listOfStrings {
if value == stringToFind {
return true
}
}
return false
}
11 changes: 10 additions & 1 deletion internal/task/gitcheck/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,18 @@ func TestRun_Dirty(t *testing.T) {

err := Task{}.Run(&context.Context{})
assert.EqualError(t, err, `uplift cannot reliably run if the repository is in a dirty state. Changes detected:
?? testing.go
[?? testing.go]

Please check and resolve the status of these files before retrying. For further
details visit: https://upliftci.dev/faq/gitdirty
`)
}

func TestRun_IncludeArtifactsWithConfiguredFiles(t *testing.T) {
gittest.InitRepository(t, gittest.WithFiles("testing.go"))

err := Task{}.Run(&context.Context{
IncludeArtifacts: []string{"testing.go"},
})
assert.NoError(t, err)
}
4 changes: 3 additions & 1 deletion internal/task/gitcheck/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ package gitcheck
import (
"errors"
"fmt"

git "github.com/purpleclay/gitz"
)

// ErrDirty is raised when a git repository has un-committed and/or un-staged changes
type ErrDirty struct {
status string
status []git.FileStatus
}

// Error returns a formatted message of the current error
Expand Down