func()

in devapp/release.go [191:324]


func (s *server) updateReleaseData() {
	log.Println("Updating release data ...")
	s.cMu.Lock()
	defer s.cMu.Unlock()

	dirToCLs := map[string][]*gerritCL{}
	issueToCLs := map[int32][]*gerritCL{}
	s.corpus.Gerrit().ForeachProjectUnsorted(func(p *maintner.GerritProject) error {
		p.ForeachOpenCL(func(cl *maintner.GerritCL) error {
			if strings.HasPrefix(cl.Subject(), prefixDev) {
				return nil
			}

			var (
				pkgs, title   = ParsePrefixedChangeTitle(projectRoot(p), cl.Subject())
				closed        bool
				closedVersion int32
				milestone     string
			)
			for _, m := range cl.Messages {
				if closed && closedVersion < m.Version {
					closed = false
				}
				sm := annotationRE.FindStringSubmatch(m.Message)
				if sm == nil {
					continue
				}
				val := sm[1]
				if val == "close" || val == "closed" {
					closedVersion = m.Version
					closed = true
				} else if milestoneRE.MatchString(val) {
					milestone = val
				}
			}
			gcl := &gerritCL{
				GerritCL:      cl,
				NoPrefixTitle: title,
				Closed:        closed,
				Milestone:     milestone,
			}

			for _, r := range cl.GitHubIssueRefs {
				issueToCLs[r.Number] = append(issueToCLs[r.Number], gcl)
			}
			if len(pkgs) == 0 {
				dirToCLs[""] = append(dirToCLs[""], gcl)
			} else {
				for _, p := range pkgs {
					dirToCLs[p] = append(dirToCLs[p], gcl)
				}
			}
			return nil
		})
		return nil
	})

	// Determine current milestone based on the highest go1.X tag.
	var highestGo1X int
	s.proj.ForeachNonChangeRef(func(ref string, _ maintner.GitHash) error {
		if !strings.HasPrefix(ref, "refs/tags/go1.") {
			return nil
		}
		tagName := ref[len("refs/tags/"):]
		if _, x, _, ok := version.ParseTag(tagName); ok && x > highestGo1X {
			highestGo1X = x
		}
		return nil
	})
	// The title of the current release milestone in GitHub. For example, "Go1.18".
	curMilestoneTitle := fmt.Sprintf("Go1.%d", highestGo1X+1)
	// The start date of the current release milestone, approximated by taking the
	// Go 1.17 release date, and adding 6 months for each successive major release.
	var monthsSinceGo117Release = time.Month(6 * (highestGo1X - 17))
	curMilestoneStart := time.Date(2021, time.August+monthsSinceGo117Release, 1, 0, 0, 0, 0, time.UTC)

	dirToIssues := map[string][]*maintner.GitHubIssue{}
	var curMilestoneIssues []*maintner.GitHubIssue
	s.repo.ForeachIssue(func(issue *maintner.GitHubIssue) error {
		// Only include issues in active milestones.
		if issue.Milestone.IsUnknown() || issue.Milestone.Closed || issue.Milestone.IsNone() {
			return nil
		}

		if issue.Milestone.Title == curMilestoneTitle {
			curMilestoneIssues = append(curMilestoneIssues, issue)
		}

		// Only open issues are displayed on the page using dirToIssues.
		if issue.Closed {
			return nil
		}

		dirs := titleDirs(issue.Title)
		if len(dirs) == 0 {
			dirToIssues[""] = append(dirToIssues[""], issue)
		} else {
			for _, d := range dirs {
				dirToIssues[d] = append(dirToIssues[d], issue)
			}
		}
		return nil
	})

	bd := burndownData{Milestone: curMilestoneTitle}
	for t, now := curMilestoneStart, time.Now(); t.Before(now); t = t.Add(24 * time.Hour) {
		var e burndownEntry
		for _, issue := range curMilestoneIssues {
			if issue.Created.After(t) || (issue.Closed && issue.ClosedAt.Before(t)) {
				continue
			}
			if issue.HasLabel("release-blocker") {
				e.Blockers++
			}
			e.Open++
		}
		e.DateStr = t.Format("01-02")
		bd.Entries = append(bd.Entries, e)
	}

	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(bd); err != nil {
		log.Printf("json.Encode: %v", err)
	}
	s.data.release.BurndownJSON = template.JS(buf.String())
	s.data.release.Sections = nil
	s.appendOpenIssues(dirToIssues, issueToCLs)
	s.appendPendingCLs(dirToCLs)
	s.appendPendingProposals(issueToCLs)
	s.appendClosedIssues()
	s.data.release.CurMilestone = curMilestoneTitle
	s.data.release.LastUpdated = time.Now().UTC().Format(time.UnixDate)
	s.data.release.dirty = false
}