func WriteReleaseNotes()

in cmd/release-notes/main.go [275:379]


func WriteReleaseNotes(releaseNotes *notes.ReleaseNotes) (err error) {
	logrus.Infof(
		"Got %d release notes, performing rendering",
		len(releaseNotes.History()),
	)

	var (
		// Open a handle to the file which will contain the release notes output
		output        *os.File
		existingNotes notes.ReleaseNotesByPR
	)

	if releaseNotesOpts.outputFile != "" {
		output, err = os.OpenFile(releaseNotesOpts.outputFile, os.O_RDWR|os.O_CREATE, os.FileMode(0o644))
		if err != nil {
			return errors.Wrapf(err, "opening the supplied output file")
		}
	} else {
		output, err = os.CreateTemp("", "release-notes-")
		if err != nil {
			return errors.Wrapf(err, "creating a temporary file to write the release notes to")
		}
	}

	// Contextualized release notes can be printed in a variety of formats
	if opts.Format == options.FormatJSON {
		byteValue, err := io.ReadAll(output)
		if err != nil {
			return err
		}

		if len(byteValue) > 0 {
			if err := json.Unmarshal(byteValue, &existingNotes); err != nil {
				return errors.Wrapf(err, "unmarshalling existing notes")
			}
		}

		if len(existingNotes) > 0 {
			if err := output.Truncate(0); err != nil {
				return err
			}
			if _, err := output.Seek(0, 0); err != nil {
				return err
			}

			for i := 0; i < len(existingNotes); i++ {
				pr := existingNotes[i].PrNumber
				if releaseNotes.Get(pr) == nil {
					releaseNotes.Set(pr, existingNotes[i])
				}
			}
		}

		enc := json.NewEncoder(output)
		enc.SetIndent("", "  ")
		if err := enc.Encode(releaseNotes.ByPR()); err != nil {
			return errors.Wrapf(err, "encoding JSON output")
		}
	} else {
		doc, err := document.New(releaseNotes, opts.StartRev, opts.EndRev)
		if err != nil {
			return errors.Wrapf(err, "creating release note document")
		}

		markdown, err := doc.RenderMarkdownTemplate(opts.ReleaseBucket, opts.ReleaseTars, "", opts.GoTemplate)
		if err != nil {
			return errors.Wrapf(err, "rendering release note document with template")
		}

		const nl = "\n"
		if releaseNotesOpts.dependencies {
			if opts.StartSHA == opts.EndSHA {
				logrus.Info("Skipping dependency report because start and end SHA are the same")
			} else {
				url := git.GetRepoURL(opts.GithubOrg, opts.GithubRepo, false)
				deps, err := notes.NewDependencies().ChangesForURL(
					url, opts.StartSHA, opts.EndSHA,
				)
				if err != nil {
					return errors.Wrap(err, "generating dependency report")
				}
				markdown += strings.Repeat(nl, 2) + deps
			}
		}

		if releaseNotesOpts.tableOfContents {
			toc, err := mdtoc.GenerateTOC([]byte(markdown), mdtoc.Options{
				Dryrun:     false,
				SkipPrefix: false,
				MaxDepth:   mdtoc.MaxHeaderDepth,
			})
			if err != nil {
				return errors.Wrap(err, "generating table of contents")
			}
			markdown = toc + nl + markdown
		}

		if _, err := output.WriteString(markdown); err != nil {
			return errors.Wrap(err, "writing output file")
		}
	}

	logrus.Infof("Release notes written to file: %s", output.Name())
	return nil
}