Skip to content

Commit

Permalink
Merge pull request #1159 from diggerhq/fix/plan-pr-number-access
Browse files Browse the repository at this point in the history
use digger generated PR output rather than from github job
  • Loading branch information
ZIJ authored Feb 15, 2024
2 parents a98a2e5 + 6f76059 commit 0b9679a
Show file tree
Hide file tree
Showing 16 changed files with 210 additions and 42 deletions.
27 changes: 10 additions & 17 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,16 @@ runs:
go-version: '^1.21.1'
if: ${{ !startsWith(github.action_ref, 'v') }}

- name: Adding required env vars for next step
uses: actions/github-script@v7
env:
github-token: $GITHUB_TOKEN
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env['ACTIONS_CACHE_URL'])
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env['ACTIONS_RUNTIME_TOKEN'])
core.exportVariable('ACTIONS_RUNTIME_URL', process.env['ACTIONS_RUNTIME_URL'])
- name: build and run digger
if: ${{ !startsWith(github.action_ref, 'v') }}
Expand Down Expand Up @@ -305,23 +315,6 @@ runs:
PATH=$PATH:$(pwd)
cd $GITHUB_WORKSPACE
digger
- name: generate artifact name based on issue number or pr number
id: artifact
shell: bash
run: |
if [[ "${{ github.event_name }}" == "issue_comment" ]]; then
echo "artifact=plans-${{ github.event.issue.number }}" >> $GITHUB_OUTPUT
else
echo "artifact=plans-${{ github.event.number }}" >> $GITHUB_OUTPUT
fi
- name: upload plan
uses: actions/upload-artifact@v4
with:
name: ${{ steps.artifact.outputs.artifact }}
path: '${{ github.workspace }}/**/*.tfplan'
retention-days: 14
if: ${{ inputs.upload-plan-destination == 'github' }}

branding:
icon: globe
color: purple
10 changes: 10 additions & 0 deletions cli/cmd/digger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ func gitHubCI(lock core_locking.Lock, policyChecker core_policy.Checker, backend
err = json.Unmarshal([]byte(inputs.JobString), &job)
commentId64, err := strconv.ParseInt(inputs.CommentId, 10, 64)

err = githubPrService.SetOutput(*job.PullRequestNumber, "DIGGER_PR_NUMBER", fmt.Sprintf("%v", *job.PullRequestNumber))
if err != nil {
reportErrorAndExit(githubActor, fmt.Sprintf("Failed to set job output. Exiting. %s", err), 4)
}

if err != nil {
reportErrorAndExit(githubActor, fmt.Sprintf("Failed to parse jobs json. %s", err), 4)
}
Expand Down Expand Up @@ -313,6 +318,11 @@ func gitHubCI(lock core_locking.Lock, policyChecker core_policy.Checker, backend
log.Println("GitHub event converted to commands successfully")
logCommands(jobs)

err = githubPrService.SetOutput(prNumber, "DIGGER_PR_NUMBER", fmt.Sprintf("%v", prNumber))
if err != nil {
reportErrorAndExit(githubActor, fmt.Sprintf("Failed to set job output. Exiting. %s", err), 4)
}

planStorage := newPlanStorage(ghToken, repoOwner, repositoryName, githubActor, &prNumber)

reporter := &reporting.CiReporter{
Expand Down
5 changes: 5 additions & 0 deletions cli/pkg/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,11 @@ func (a *AzureReposService) GetBranchName(prNumber int) (string, error) {
return "", nil
}

func (svc *AzureReposService) SetOutput(prNumber int, key string, value string) error {
//TODO implement me
return nil
}

func (a *AzureReposService) GetComments(prNumber int) ([]orchestrator.Comment, error) {
comments, err := a.Client.GetComments(context.Background(), git.GetCommentsArgs{
Project: &a.ProjectName,
Expand Down
5 changes: 5 additions & 0 deletions cli/pkg/bitbucket/bitbucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,11 @@ func (b *BitbucketAPI) GetBranchName(prNumber int) (string, error) {
return pullRequest.Source.Branch.Name, nil
}

func (svc *BitbucketAPI) SetOutput(prNumber int, key string, value string) error {
//TODO implement me
return nil
}

// Implement the OrgService interface.

func (b *BitbucketAPI) GetUserTeams(organisation string, user string) ([]string, error) {
Expand Down
25 changes: 13 additions & 12 deletions cli/pkg/core/execution/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ type DiggerExecutorPlanResult struct {
type PlanPathProvider interface {
LocalPlanFilePath() string
StoredPlanFilePath() string
ArtifactName() string
PlanFileName() string
}

Expand All @@ -126,8 +127,12 @@ type ProjectPathProvider struct {
ProjectName string
}

func (d ProjectPathProvider) ArtifactName() string {
return d.ProjectName
}

func (d ProjectPathProvider) PlanFileName() string {
return strings.ReplaceAll(d.ProjectNamespace, "/", "-") + "#" + d.ProjectName + ".tfplan"
return strings.ReplaceAll(d.ProjectNamespace, "/", "-") + "-" + d.ProjectName + ".tfplan"
}

func (d ProjectPathProvider) LocalPlanFilePath() string {
Expand Down Expand Up @@ -193,21 +198,17 @@ func (d DiggerExecutor) Plan() (*terraform.PlanSummary, bool, bool, string, stri
return nil, false, false, "", "", fmt.Errorf("error executing plan: %v", err)
}
if d.PlanStorage != nil {
planExists, err := d.PlanStorage.PlanExists(d.PlanPathProvider.StoredPlanFilePath())
if err != nil {
return nil, false, false, "", "", fmt.Errorf("error checking if plan exists: %v", err)
}

if planExists {
err = d.PlanStorage.DeleteStoredPlan(d.PlanPathProvider.StoredPlanFilePath())
if err != nil {
return nil, false, false, "", "", fmt.Errorf("error deleting plan: %v", err)
}
fileBytes, err := os.ReadFile(d.PlanPathProvider.LocalPlanFilePath())
if err != nil {
fmt.Println("Error reading file:", err)
return nil, false, false, "", "", fmt.Errorf("error reading file bytes: %v", err)
}

err = d.PlanStorage.StorePlan(d.PlanPathProvider.LocalPlanFilePath(), d.PlanPathProvider.StoredPlanFilePath())
err = d.PlanStorage.StorePlanFile(fileBytes, d.PlanPathProvider.ArtifactName(), d.PlanPathProvider.PlanFileName())
if err != nil {
return nil, false, false, "", "", fmt.Errorf("error storing plan: %v", err)
fmt.Println("Error storing artifact file:", err)
return nil, false, false, "", "", fmt.Errorf("error storing artifact file: %v", err)
}
}
plan = cleanupTerraformPlan(!isEmptyPlan, err, stdout, stderr)
Expand Down
1 change: 1 addition & 0 deletions cli/pkg/core/storage/plan_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package storage

type PlanStorage interface {
StorePlan(localPlanFilePath string, storedPlanFilePath string) error
StorePlanFile(fileContents []byte, artifactName string, fileName string) error
RetrievePlan(localPlanFilePath string, storedPlanFilePath string) (*string, error)
DeleteStoredPlan(storedPlanFilePath string) error
PlanExists(storedPlanFilePath string) (bool, error)
Expand Down
8 changes: 4 additions & 4 deletions cli/pkg/digger/digger.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ func run(command string, job orchestrator.Job, policyChecker policy.Checker, org
var planPolicyViolations []string

if os.Getenv("PLAN_UPLOAD_DESTINATION") != "" {
storedPlanJson, err := retrievePlanBeforeApply(planStorage, planPathProvider, diggerExecutor)
storedPlanJson, err := retrievePlanBeforeApply(planStorage, planPathProvider, diggerExecutor.Executor.(execution.DiggerExecutor))
if err != nil {
msg := fmt.Sprintf("Failed to retrieve stored plan. %v", err)
log.Printf(msg)
Expand Down Expand Up @@ -485,14 +485,14 @@ func run(command string, job orchestrator.Job, policyChecker policy.Checker, org
return &execution.DiggerExecutorResult{}, "", nil
}

func retrievePlanBeforeApply(planStorage storage.PlanStorage, planPathProvider execution.PlanPathProvider, diggerExecutor execution.LockingExecutorWrapper) (string, error) {
storedPlanExists, err := planStorage.PlanExists(planPathProvider.StoredPlanFilePath())
func retrievePlanBeforeApply(planStorage storage.PlanStorage, planPathProvider execution.PlanPathProvider, diggerExecutor execution.DiggerExecutor) (string, error) {
storedPlanExists, err := planStorage.PlanExists(diggerExecutor.ProjectName)
if err != nil {
return "", fmt.Errorf("failed to check if stored plan exists. %v", err)
}
if storedPlanExists {
log.Printf("Pre-apply plan retrieval: stored plan exists")
storedPlanPath, err := planStorage.RetrievePlan(planPathProvider.LocalPlanFilePath(), planPathProvider.StoredPlanFilePath())
storedPlanPath, err := planStorage.RetrievePlan(planPathProvider.LocalPlanFilePath(), planPathProvider.ArtifactName())
if err != nil {
return "", fmt.Errorf("failed to retrieve stored plan path. %v", err)
}
Expand Down
22 changes: 21 additions & 1 deletion cli/pkg/digger/digger_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package digger

import (
"os"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -137,6 +138,12 @@ func (m *MockPRManager) GetBranchName(prNumber int) (string, error) {
return "", nil
}

func (m *MockPRManager) SetOutput(prNumber int, key string, value string) error {
m.Commands = append(m.Commands, RunInfo{"SetOutput", strconv.Itoa(prNumber), time.Now()})
return nil

}

type MockProjectLock struct {
Commands []RunInfo
}
Expand Down Expand Up @@ -179,6 +186,11 @@ func (m *MockPlanStorage) StorePlan(localPlanFilePath string, storedPlanFilePath
return nil
}

func (m *MockPlanStorage) StorePlanFile(fileContents []byte, artifactName string, fileName string) error {
m.Commands = append(m.Commands, RunInfo{"StorePlanFile", artifactName, time.Now()})
return nil
}

func (m *MockPlanStorage) RetrievePlan(localPlanFilePath string, storedPlanFilePath string) (*string, error) {
m.Commands = append(m.Commands, RunInfo{"RetrievePlan", localPlanFilePath, time.Now()})
return nil, nil
Expand All @@ -198,6 +210,11 @@ type MockPlanPathProvider struct {
Commands []RunInfo
}

func (m MockPlanPathProvider) ArtifactName() string {
m.Commands = append(m.Commands, RunInfo{"ArtifactName", "", time.Now()})
return "plan"
}

func (m MockPlanPathProvider) PlanFileName() string {
m.Commands = append(m.Commands, RunInfo{"PlanFileName", "", time.Now()})
return "plan"
Expand Down Expand Up @@ -344,11 +361,14 @@ func TestCorrectCommandExecutionWhenPlanning(t *testing.T) {
PlanPathProvider: planPathProvider,
}

os.WriteFile(planPathProvider.LocalPlanFilePath(), []byte{123}, 0644)
defer os.Remove(planPathProvider.LocalPlanFilePath())

executor.Plan()

commandStrings := allCommandsInOrderWithParams(terraformExecutor, commandRunner, prManager, lock, planStorage, planPathProvider)

assert.Equal(t, []string{"Init ", "Plan -out plan -lock-timeout=3m", "Show -no-color -json plan", "PlanExists plan", "StorePlan plan", "Run echo"}, commandStrings)
assert.Equal(t, []string{"Init ", "Plan -out plan -lock-timeout=3m", "Show -no-color -json plan", "StorePlanFile plan", "Run echo"}, commandStrings)
}

func allCommandsInOrderWithParams(terraformExecutor *MockTerraformExecutor, commandRunner *MockCommandRunner, prManager *MockPRManager, lock *MockProjectLock, planStorage *MockPlanStorage, planPathProvider *MockPlanPathProvider) []string {
Expand Down
5 changes: 5 additions & 0 deletions cli/pkg/github/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,8 @@ func (t MockCiService) EditComment(prNumber int, commentId interface{}, comment
func (t MockCiService) GetBranchName(prNumber int) (string, error) {
return "", nil
}

func (svc MockCiService) SetOutput(prNumber int, key string, value string) error {
//TODO implement me
return nil
}
5 changes: 5 additions & 0 deletions cli/pkg/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ func (gitlabService GitLabService) GetBranchName(prNumber int) (string, error) {
return "", nil
}

func (svc *GitLabService) SetOutput(prNumber int, key string, value string) error {
//TODO implement me
return nil
}

func getMergeRequest(gitlabService GitLabService) *go_gitlab.MergeRequest {
projectId := *gitlabService.Context.ProjectId
mergeRequestIID := *gitlabService.Context.MergeRequestIId
Expand Down
4 changes: 4 additions & 0 deletions cli/pkg/reporting/reporting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,7 @@ func (t MockCiService) EditComment(prNumber int, commentId interface{}, comment
func (t MockCiService) GetBranchName(prNumber int) (string, error) {
return "", nil
}

func (svc MockCiService) SetOutput(prNumber int, key string, value string) error {
return nil
}
Loading

0 comments on commit 0b9679a

Please sign in to comment.