diff --git a/actions/stack/diff-package-receipts/action.yml b/actions/stack/diff-package-receipts/action.yml index a74402ab..bbab2d7c 100644 --- a/actions/stack/diff-package-receipts/action.yml +++ b/actions/stack/diff-package-receipts/action.yml @@ -8,14 +8,15 @@ inputs: current: description: 'Path to current package receipt' required: true - -outputs: - added: + added_diff_file: description: 'List of packages added' - removed: + required: true + removed_diff_file: description: 'List of packages removed' - modified: + required: true + modified_diff_file: description: 'List of packages modified' + required: true runs: using: 'docker' @@ -25,3 +26,9 @@ runs: - "${{ inputs.previous }}" - "--current" - "${{ inputs.current }}" + - "--added-diff-file" + - "${{ inputs.added_diff_file }}" + - "--removed-diff-file" + - "${{ inputs.removed_diff_file }}" + - "--modified-diff-file" + - "${{ inputs.modified_diff_file }}" diff --git a/actions/stack/diff-package-receipts/entrypoint/main.go b/actions/stack/diff-package-receipts/entrypoint/main.go index 48424e00..2b41c042 100644 --- a/actions/stack/diff-package-receipts/entrypoint/main.go +++ b/actions/stack/diff-package-receipts/entrypoint/main.go @@ -29,8 +29,11 @@ type ModifiedCycloneDXComponent struct { func main() { var config struct { - CurrentPath string - PreviousPath string + CurrentPath string + PreviousPath string + AddedDiffFilePath string + RemovedDiffFilePath string + ModifiedDiffFilePath string } flag.StringVar(&config.PreviousPath, @@ -43,12 +46,31 @@ func main() { "", "Path to current package receipt") + flag.StringVar(&config.AddedDiffFilePath, + "added-diff-file", + "", + "List of packages added") + + flag.StringVar(&config.RemovedDiffFilePath, + "removed-diff-file", + "", + "List of packages removed") + + flag.StringVar(&config.ModifiedDiffFilePath, + "modified-diff-file", + "", + "List of packages modified") + flag.Parse() if config.CurrentPath == "" || config.PreviousPath == "" { log.Fatal("Must provide current and previous paths") } + if config.AddedDiffFilePath == "" || config.RemovedDiffFilePath == "" || config.ModifiedDiffFilePath == "" { + log.Fatal("Must provide diff file paths") + } + absolute, err := filepath.Abs(config.CurrentPath) if err != nil { log.Fatalf("Failed to create absolute path for %s", config.CurrentPath) @@ -61,6 +83,24 @@ func main() { } config.PreviousPath = absolute + absolute, err = filepath.Abs(config.AddedDiffFilePath) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.AddedDiffFilePath) + } + config.AddedDiffFilePath = absolute + + absolute, err = filepath.Abs(config.RemovedDiffFilePath) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.RemovedDiffFilePath) + } + config.RemovedDiffFilePath = absolute + + absolute, err = filepath.Abs(config.ModifiedDiffFilePath) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.ModifiedDiffFilePath) + } + config.ModifiedDiffFilePath = absolute + previous, err := parsePackagesFromFile(config.PreviousPath) if err != nil { log.Fatal(err) @@ -99,28 +139,37 @@ func main() { } } - addedJSON, err := json.Marshal(added) + addedFile, err := os.OpenFile(config.AddedDiffFilePath, os.O_RDWR|os.O_CREATE, 0666) if err != nil { log.Fatal(err) } - if len(added) == 0 { - addedJSON = []byte(`[]`) + defer addedFile.Close() + + err = json.NewEncoder(addedFile).Encode(&added) + if err != nil { + log.Fatal(err) } - removedJSON, err := json.Marshal(removed) + removedFile, err := os.OpenFile(config.RemovedDiffFilePath, os.O_RDWR|os.O_CREATE, 0666) if err != nil { log.Fatal(err) } - if len(removed) == 0 { - removedJSON = []byte(`[]`) + defer removedFile.Close() + + err = json.NewEncoder(removedFile).Encode(&removed) + if err != nil { + log.Fatal(err) } - modifiedJSON, err := json.Marshal(modified) + modifiedFile, err := os.OpenFile(config.ModifiedDiffFilePath, os.O_RDWR|os.O_CREATE, 0666) if err != nil { log.Fatal(err) } - if len(modified) == 0 { - modifiedJSON = []byte(`[]`) + defer modifiedFile.Close() + + err = json.NewEncoder(modifiedFile).Encode(&modified) + if err != nil { + log.Fatal(err) } fmt.Println("Added packages:") @@ -141,19 +190,6 @@ func main() { pkg.CurrentPURL, ) } - - outputFileName, ok := os.LookupEnv("GITHUB_OUTPUT") - if !ok { - log.Fatal("GITHUB_OUTPUT is not set, see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter") - } - file, err := os.OpenFile(outputFileName, os.O_APPEND|os.O_WRONLY, 0) - if err != nil { - log.Fatal(err) - } - defer file.Close() - fmt.Fprintf(file, "added=%s\n", string(addedJSON)) - fmt.Fprintf(file, "removed=%s\n", string(removedJSON)) - fmt.Fprintf(file, "modified=%s\n", string(modifiedJSON)) } func parsePackagesFromFile(path string) (map[string]CycloneDXComponent, error) { diff --git a/actions/stack/release-notes/action.yml b/actions/stack/release-notes/action.yml index 8257c19e..64b8ccac 100644 --- a/actions/stack/release-notes/action.yml +++ b/actions/stack/release-notes/action.yml @@ -21,22 +21,22 @@ inputs: description: 'CVE scan report path of run image in markdown format' required: false build_packages_added: - description: 'JSON array of packages added "{ name: name, version: 1.2.3 }"' + description: 'Path to build packages added file' required: false build_packages_modified: - description: 'JSON array of packages modified "{ name: name, previousVersion: 1.2.3, currentVersion: 1.2.4 }"' + description: 'Path to build packages modified file' required: false build_packages_removed_with_force: - description: 'JSON array of packages removed with user-provided force "{ name: name, version: 1.2.3}"' + description: 'Path to build packages removed file' required: false run_packages_added: - description: 'JSON array of packages added "{ name: name, version: 1.2.3 }"' + description: 'Path to run packages added file' required: false run_packages_modified: - description: 'JSON array of packages modified "{ name: name, previousVersion: 1.2.3, currentVersion: 1.2.4 }"' + description: 'Path to run packages modified file' required: false run_packages_removed_with_force: - description: 'JSON array of packages removed with user-provided force "{ name: name, version: 1.2.3}"' + description: 'Path to run packages removed file' required: false patched_usns: description: 'JSON array of objects "{ name: USN name, url: USN URL, description: USN description}"' diff --git a/actions/stack/release-notes/entrypoint/main.go b/actions/stack/release-notes/entrypoint/main.go index 5c280a5e..6db7f825 100644 --- a/actions/stack/release-notes/entrypoint/main.go +++ b/actions/stack/release-notes/entrypoint/main.go @@ -10,6 +10,7 @@ import ( "fmt" "log" "os" + "path/filepath" "strconv" "text/template" ) @@ -69,6 +70,42 @@ func main() { flag.StringVar(&config.ReceiptsShowLimit, "receipts-show-limit", "", "Integer which defines the limit of whether it should show or not the receipts array of each image") flag.Parse() + absolute, err := filepath.Abs(config.BuildPackagesAddedJSON) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.BuildPackagesAddedJSON) + } + config.BuildPackagesAddedJSON = absolute + + absolute, err = filepath.Abs(config.BuildPackagesModifiedJSON) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.BuildPackagesModifiedJSON) + } + config.BuildPackagesModifiedJSON = absolute + + absolute, err = filepath.Abs(config.BuildPackagesRemovedJSON) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.BuildPackagesRemovedJSON) + } + config.BuildPackagesRemovedJSON = absolute + + absolute, err = filepath.Abs(config.RunPackagesAddedJSON) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.RunPackagesAddedJSON) + } + config.RunPackagesAddedJSON = absolute + + absolute, err = filepath.Abs(config.RunPackagesModifiedJSON) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.RunPackagesModifiedJSON) + } + config.RunPackagesModifiedJSON = absolute + + absolute, err = filepath.Abs(config.RunPackagesRemovedJSON) + if err != nil { + log.Fatalf("Failed to create absolute path for %s", config.RunPackagesRemovedJSON) + } + config.RunPackagesRemovedJSON = absolute + var contents struct { PatchedArray []USN SupportsUsns bool @@ -85,7 +122,7 @@ func main() { ReceiptsShowLimit int } - err := json.Unmarshal([]byte(fixEmptyArray(config.PatchedJSON)), &contents.PatchedArray) + err = json.Unmarshal([]byte(fixEmptyArray(config.PatchedJSON)), &contents.PatchedArray) if err != nil { log.Fatalf("failed unmarshalling patched USNs: %s", err.Error()) } @@ -99,32 +136,68 @@ func main() { } } - err = json.Unmarshal([]byte(fixEmptyArray(config.BuildPackagesAddedJSON)), &contents.BuildAdded) + buildAddedFile, err := os.Open(config.BuildPackagesAddedJSON) + if err != nil { + log.Fatal(err) + } + defer buildAddedFile.Close() + + err = json.NewDecoder(buildAddedFile).Decode(&contents.BuildAdded) if err != nil { log.Fatalf("failed unmarshalling build packages added: %s", err.Error()) } - err = json.Unmarshal([]byte(fixEmptyArray(config.BuildPackagesModifiedJSON)), &contents.BuildModified) + buildModifiedFile, err := os.Open(config.BuildPackagesModifiedJSON) + if err != nil { + log.Fatal(err) + } + defer buildModifiedFile.Close() + + err = json.NewDecoder(buildModifiedFile).Decode(&contents.BuildModified) if err != nil { log.Fatalf("failed unmarshalling build packages modified: %s", err.Error()) } - err = json.Unmarshal([]byte(fixEmptyArray(config.BuildPackagesRemovedJSON)), &contents.BuildRemoved) + buildRemovedFile, err := os.Open(config.BuildPackagesRemovedJSON) + if err != nil { + log.Fatal(err) + } + defer buildRemovedFile.Close() + + err = json.NewDecoder(buildRemovedFile).Decode(&contents.BuildRemoved) if err != nil { log.Fatalf("failed unmarshalling build packages removed: %s", err.Error()) } - err = json.Unmarshal([]byte(fixEmptyArray(config.RunPackagesAddedJSON)), &contents.RunAdded) + runAddedFile, err := os.Open(config.RunPackagesAddedJSON) + if err != nil { + log.Fatal(err) + } + defer runAddedFile.Close() + + err = json.NewDecoder(runAddedFile).Decode(&contents.RunAdded) if err != nil { log.Fatalf("failed unmarshalling run packages added: %s", err.Error()) } - err = json.Unmarshal([]byte(fixEmptyArray(config.RunPackagesModifiedJSON)), &contents.RunModified) + runModifiedFile, err := os.Open(config.RunPackagesModifiedJSON) + if err != nil { + log.Fatal(err) + } + defer runModifiedFile.Close() + + err = json.NewDecoder(runModifiedFile).Decode(&contents.RunModified) if err != nil { log.Fatalf("failed unmarshalling run packages modified: %s", err.Error()) } - err = json.Unmarshal([]byte(fixEmptyArray(config.RunPackagesRemovedJSON)), &contents.RunRemoved) + runRemovedFile, err := os.Open(config.RunPackagesRemovedJSON) + if err != nil { + log.Fatal(err) + } + defer runRemovedFile.Close() + + err = json.NewDecoder(runRemovedFile).Decode(&contents.RunRemoved) if err != nil { log.Fatalf("failed unmarshalling run packages removed: %s", err.Error()) } diff --git a/stack/.github/workflows/create-release.yml b/stack/.github/workflows/create-release.yml index c254c617..d25dcff6 100644 --- a/stack/.github/workflows/create-release.yml +++ b/stack/.github/workflows/create-release.yml @@ -25,6 +25,12 @@ env: BUILD_RECEIPT_FILENAME: "build-receipt.cyclonedx.json" RUN_RECEIPT_FILENAME: "run-receipt.cyclonedx.json" PATCHED_USNS_FILENAME: "patched-usns.json" + BUILD_DIFF_ADDED_FILENAME: "build-diff-added.json" + BUILD_DIFF_MODIFIED_FILENAME: "build-diff-modified.json" + BUILD_DIFF_REMOVED_FILENAME: "build-diff-removed.json" + RUN_DIFF_ADDED_FILENAME: "run-diff-added.json" + RUN_DIFF_MODIFIED_FILENAME: "run-diff-modified.json" + RUN_DIFF_REMOVED_FILENAME: "run-diff-removed.json" jobs: poll_usns: name: Poll USNs @@ -183,12 +189,6 @@ jobs: diff: name: Diff Packages outputs: - build_added: ${{ steps.build_diff.outputs.added }} - build_modified: ${{ steps.build_diff.outputs.modified }} - build_removed_with_force: ${{ steps.build_diff.outputs.removed }} - run_added: ${{ steps.run_diff.outputs.added }} - run_modified: ${{ steps.run_diff.outputs.modified }} - run_removed_with_force: ${{ steps.run_diff.outputs.removed }} removed_with_force: ${{ steps.removed_with_force.outputs.packages_removed }} needs: [ create_stack ] runs-on: ubuntu-24.04 @@ -248,6 +248,9 @@ jobs: with: previous: "/github/workspace/previous-${{ env.BUILD_RECEIPT_FILENAME }}" current: "/github/workspace/${{ env.BUILD_RECEIPT_FILENAME }}" + added_diff_file: "/github/workspace/${{ env.BUILD_DIFF_ADDED_FILENAME }}" + modified_diff_file: "/github/workspace/${{ env.BUILD_DIFF_MODIFIED_FILENAME }}" + removed_diff_file: "/github/workspace/${{ env.BUILD_DIFF_REMOVED_FILENAME }}" - name: Compare Run Packages id: run_diff @@ -255,14 +258,17 @@ jobs: with: previous: "/github/workspace/previous-${{ env.RUN_RECEIPT_FILENAME }}" current: "/github/workspace/${{ env.RUN_RECEIPT_FILENAME }}" + added_diff_file: "/github/workspace/${{ env.RUN_DIFF_ADDED_FILENAME }}" + modified_diff_file: "/github/workspace/${{ env.RUN_DIFF_MODIFIED_FILENAME }}" + removed_diff_file: "/github/workspace/${{ env.RUN_DIFF_REMOVED_FILENAME }}" - name: Fail If Packages Removed id: removed_with_force run: | - build=$(jq '. | length' <<< "${BUILD_REMOVED}") + build=$(jq '. | length' "${BUILD_REMOVED}") echo "Build packages removed: ${build}" - run=$(jq '. | length' <<< "${RUN_REMOVED}") + run=$(jq '. | length' "${RUN_REMOVED}") echo "Run packages removed: ${run}" # only fail if packages are removed AND the release has not been forced @@ -277,8 +283,8 @@ jobs: echo "packages_removed=false" >> "$GITHUB_OUTPUT" fi env: - BUILD_REMOVED: ${{ steps.build_diff.outputs.removed }} - RUN_REMOVED: ${{ steps.run_diff.outputs.removed }} + BUILD_REMOVED: "/github/workspace/${{ env.BUILD_DIFF_REMOVED_FILENAME }}" + RUN_REMOVED: "/github/workspace/${{ env.RUN_DIFF_REMOVED_FILENAME }}" run_if_packages_removed_with_force: name: Run If Packages Removed With Force @@ -301,19 +307,19 @@ jobs: id: compare run: | # shellcheck disable=SC2153 - build_added=$(jq '. | length' <<< "${BUILD_ADDED}") + build_added=$(jq '. | length' "${BUILD_ADDED}") echo "Build packages added: ${build_added}" # shellcheck disable=SC2153 - build_modified=$(jq '. | length' <<< "${BUILD_MODIFIED}") + build_modified=$(jq '. | length' "${BUILD_MODIFIED}") echo "Build packages modified: ${build_modified}" # shellcheck disable=SC2153 - run_added=$(jq '. | length' <<< "${RUN_ADDED}") + run_added=$(jq '. | length' "${RUN_ADDED}") echo "Run packages added: ${run_added}" # shellcheck disable=SC2153 - run_modified=$(jq '. | length' <<< "${RUN_MODIFIED}") + run_modified=$(jq '. | length' "${RUN_MODIFIED}") echo "Run packages modified: ${run_modified}" if [ "${build_added}" -eq 0 ] && [ "${build_modified}" -eq 0 ] && [ "${run_added}" -eq 0 ] && [ "${run_modified}" -eq 0 ]; then @@ -325,10 +331,10 @@ jobs: fi env: - BUILD_ADDED: ${{ needs.diff.outputs.build_added }} - BUILD_MODIFIED: ${{ needs.diff.outputs.build_modified }} - RUN_ADDED: ${{ needs.diff.outputs.run_added }} - RUN_MODIFIED: ${{ needs.diff.outputs.run_modified }} + BUILD_ADDED: "/github/workspace/${{ env.BUILD_DIFF_ADDED_FILENAME }}" + BUILD_MODIFIED: "/github/workspace/${{ env.BUILD_DIFF_MODIFIED_FILENAME }}" + RUN_ADDED: "/github/workspace/${{ env.RUN_DIFF_ADDED_FILENAME }}" + RUN_MODIFIED: "/github/workspace/${{ env.RUN_DIFF_MODIFIED_FILENAME }}" run_if_packages_changed: name: Run If Packages Changed @@ -468,12 +474,12 @@ jobs: with: build_image: "paketobuildpacks/build-${{ steps.repo_name.outputs.registry_repo_name }}:${{ steps.tag.outputs.tag }}" run_image: "paketobuildpacks/run-${{ steps.repo_name.outputs.registry_repo_name }}:${{ steps.tag.outputs.tag }}" - build_packages_added: ${{ needs.diff.outputs.build_added }} - build_packages_modified: ${{ needs.diff.outputs.build_modified }} - build_packages_removed_with_force: ${{ needs.diff.outputs.build_removed_with_force }} - run_packages_added: ${{ needs.diff.outputs.run_added }} - run_packages_modified: ${{ needs.diff.outputs.run_modified }} - run_packages_removed_with_force: ${{ needs.diff.outputs.run_removed_with_force }} + build_packages_added: "/github/workspace/${{ env.BUILD_DIFF_ADDED_FILENAME }}" + build_packages_modified: "/github/workspace/${{ env.BUILD_DIFF_MODIFIED_FILENAME }}" + build_packages_removed_with_force: "/github/workspace/${{ env.BUILD_DIFF_REMOVED_FILENAME }}" + run_packages_added: "/github/workspace/${{ env.RUN_DIFF_ADDED_FILENAME }}" + run_packages_modified: "/github/workspace/${{ env.RUN_DIFF_MODIFIED_FILENAME }}" + run_packages_removed_with_force: "/github/workspace/${{ env.RUN_DIFF_REMOVED_FILENAME }}" patched_usns: ${{ needs.poll_usns.outputs.usns }} - name: Setup Release Assets