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

Conditionally Run Workflows Based on Git Artifact Files Changed #8415

Open
tony-mw opened this issue Apr 19, 2022 · 4 comments
Open

Conditionally Run Workflows Based on Git Artifact Files Changed #8415

tony-mw opened this issue Apr 19, 2022 · 4 comments
Labels
area/artifacts S3/GCP/OSS/Git/HDFS etc type/feature Feature request

Comments

@tony-mw
Copy link

tony-mw commented Apr 19, 2022

Summary

It would be useful to add a key:list(values) option to the git artifact stanza of the Workflow/Workflow-Template CRD where an operator can specify the paths of files that, when modified, will trigger the workflow.

  • Example:
artifacts:
  - name: my-git-repo
    path: "/home/argo"
    git:
      repo: "my-repo.git"
      depth: n
      filter:
        watchPaths:
          - service1/*

Use Cases

I ran into a scenario where I needed this functionality to set a working directory for a later stage in my workflow, based on the files changed in the repo. That was specifically for a Terraform workflow, but I could see this also being useful in monorepos containing multiple microservices where builds should only happen when code specific directories has changed.

I was able to achieve this by developing a custom go program that leverages the go-git package to derive file changes that occur when an Event triggers a Workflow. This runs as a pre-build stage in the workflow currently, and passes the working directories from one stage to the next.

Here is a snippet of my code which is triggered if the event is a pull request that I think could likely be a good starting point to add this feature. (If the event is just a commit to main or any branch that builds, there is less logic because you only have to compare the 2 latest commits instead of every ancestor of main)

	ref, _ := repo.Log(&git.LogOptions{
		From:  myBranchRef,
	})

	ref.ForEach(func(c *object.Commit) error {
		ancestor, _ := c.IsAncestor(currentCommit)
		if logger.Check() {
			log.Printf("Is ancestor: %t", ancestor)
		}
		if ancestor {
			appendOn = false
			return nil
		}
		if appendOn {
			commits = append(commits, c)
		}
		return nil
	})

	for _, v := range commits {
		diff, err := v.Patch(currentCommit)
		if err != nil {
			log.Fatal(err)
		}
		filesPatched := diff.FilePatches()
		for _, fileList := range filesPatched {
			if fileList.IsBinary() {
				log.Println("Ignoring binary files")
				continue
			}
			from, to := fileList.Files()
			if from.Path() == to.Path() {
				filesChanged = append(filesChanged, from.Path())
			} 
		}
	}

Message from the maintainers:

Love this enhancement proposal? Give it a 👍. We prioritise the proposals with the most 👍.

@tony-mw tony-mw added the type/feature Feature request label Apr 19, 2022
@alexec alexec added the area/artifacts S3/GCP/OSS/Git/HDFS etc label Apr 20, 2022
@terrytangyuan
Copy link
Member

@tony-mw
Copy link
Author

tony-mw commented Apr 28, 2022

Right, that works in GitHub... but the problem is that some source control tools don't send you which files change in their event

@terrytangyuan
Copy link
Member

File event source might be what you want: https://github.com/argoproj/argo-events/blob/master/docs/eventsources/setup/file.md

@OneCricketeer
Copy link

File event source might be what you want

Am I missing some context? How would this help with Git event trigger?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/artifacts S3/GCP/OSS/Git/HDFS etc type/feature Feature request
Projects
None yet
Development

No branches or pull requests

4 participants