Repository: google/go-github
Pull request #2870 (2023-08-14 13:37:25)

Defer closing body before checking HTTP status code
This is a quote from the [documentation](https://pkg.go.dev/net/http#example-Get) of the `net/http package`:
> When err is nil, resp always contains a non-nil resp.Body. Caller should close resp.Body when done reading from it.

In the current implementation, if the error code is 404, the response body will not close.


Patch:
diff --git a/github/event.go b/github/event.go
index 2349cb77..7ec46b5a 100644
--- a/github/event.go
+++ b/github/event.go
@@ -105,6 +105,10 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
 		payload = &ProjectCardEvent{}
 	case "ProjectColumnEvent":
 		payload = &ProjectColumnEvent{}
+	case "ProjectV2Event":
+		payload = &ProjectV2Event{}
+	case "ProjectV2ItemEvent":
+		payload = &ProjectV2ItemEvent{}
 	case "PublicEvent":
 		payload = &PublicEvent{}
 	case "PullRequestEvent":
@@ -133,6 +137,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
 		payload = &SecretScanningAlertEvent{}
 	case "SecurityAdvisoryEvent":
 		payload = &SecurityAdvisoryEvent{}
+	case "SecurityAndAnalysisEvent":
+		payload = &SecurityAndAnalysisEvent{}
 	case "StarEvent":
 		payload = &StarEvent{}
 	case "StatusEvent":
diff --git a/github/event_types.go b/github/event_types.go
index a2413447..c9e97ffa 100644
--- a/github/event_types.go
+++ b/github/event_types.go
@@ -942,6 +942,77 @@ type ProjectColumnEvent struct {
 	Installation *Installation `json:"installation,omitempty"`
 }
 
+// ProjectV2Event is triggered when there is activity relating to an organization-level project.
+// The Webhook event name is "projects_v2".
+//
+// GitHub API docs: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#projects_v2
+type ProjectV2Event struct {
+	Action     *string     `json:"action,omitempty"`
+	ProjectsV2 *ProjectsV2 `json:"projects_v2,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Installation *Installation `json:"installation,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+}
+
+// ProjectsV2 represents a projects v2 project.
+type ProjectsV2 struct {
+	ID               *int64     `json:"id,omitempty"`
+	NodeID           *string    `json:"node_id,omitempty"`
+	Owner            *User      `json:"owner,omitempty"`
+	Creator          *User      `json:"creator,omitempty"`
+	Title            *string    `json:"title,omitempty"`
+	Description      *string    `json:"description,omitempty"`
+	Public           *bool      `json:"public,omitempty"`
+	ClosedAt         *Timestamp `json:"closed_at,omitempty"`
+	CreatedAt        *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt        *Timestamp `json:"updated_at,omitempty"`
+	DeletedAt        *Timestamp `json:"deleted_at,omitempty"`
+	Number           *int       `json:"number,omitempty"`
+	ShortDescription *string    `json:"short_description,omitempty"`
+	DeletedBy        *User      `json:"deleted_by,omitempty"`
+}
+
+// ProjectV2ItemEvent is triggered when there is activity relating to an item on an organization-level project.
+// The Webhook event name is "projects_v2_item".
+//
+// GitHub API docs: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#projects_v2_item
+type ProjectV2ItemEvent struct {
+	Action        *string              `json:"action,omitempty"`
+	Changes       *ProjectV2ItemChange `json:"changes,omitempty"`
+	ProjectV2Item *ProjectV2Item       `json:"projects_v2_item,omitempty"`
+
+	// The following fields are only populated by Webhook events.
+	Installation *Installation `json:"installation,omitempty"`
+	Org          *Organization `json:"organization,omitempty"`
+	Sender       *User         `json:"sender,omitempty"`
+}
+
+// ProjectV2ItemChange represents a project v2 item change.
+type ProjectV2ItemChange struct {
+	ArchivedAt *ArchivedAt `json:"archived_at,omitempty"`
+}
+
+// ArchivedAt represents an archiving date change.
+type ArchivedAt struct {
+	From *Timestamp `json:"from,omitempty"`
+	To   *Timestamp `json:"to,omitempty"`
+}
+
+// ProjectsV2 represents an item belonging to a project.
+type ProjectV2Item struct {
+	ID            *int64     `json:"id,omitempty"`
+	NodeID        *string    `json:"node_id,omitempty"`
+	ProjectNodeID *string    `json:"project_node_id,omitempty"`
+	ContentNodeID *string    `json:"content_node_id,omitempty"`
+	ContentType   *string    `json:"content_type,omitempty"`
+	Creator       *User      `json:"creator,omitempty"`
+	CreatedAt     *Timestamp `json:"created_at,omitempty"`
+	UpdatedAt     *Timestamp `json:"updated_at,omitempty"`
+	ArchivedAt    *Timestamp `json:"archived_at,omitempty"`
+}
+
 // PublicEvent is triggered when a private repository is open sourced.
 // According to GitHub: "Without a doubt: the best GitHub event."
 // The Webhook event name is "public".
@@ -1325,6 +1396,31 @@ type SecretScanningAlertEvent struct {
 	Installation *Installation `json:"installation,omitempty"`
 }
 
+// SecurityAndAnalysisEvent is triggered when code security and analysis features
+// are enabled or disabled for a repository.
+//
+// GitHub API docs: https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads#security_and_analysis
+type SecurityAndAnalysisEvent struct {
+	Changes      *SecurityAndAnalysisChange `json:"changes,omitempty"`
+	Enterprise   *Enterprise                `json:"enterprise,omitempty"`
+	Installation *Installation              `json:"installation,omitempty"`
+	Organization *Organization              `json:"organization,omitempty"`
+	Repository   *Repository                `json:"repository,omitempty"`
+	Sender       *User                      `json:"sender,omitempty"`
+}
+
+// SecurityAndAnalysisChange represents the changes when security and analysis
+// features are enabled or disabled for a repository.
+type SecurityAndAnalysisChange struct {
+	From *SecurityAndAnalysisChangeFrom `json:"from,omitempty"`
+}
+
+// SecurityAndAnalysisChangeFrom represents which change was made when security
+// and analysis features are enabled or disabled for a repository.
+type SecurityAndAnalysisChangeFrom struct {
+	SecurityAndAnalysis *SecurityAndAnalysis `json:"security_and_analysis,omitempty"`
+}
+
 // StarEvent is triggered when a star is added or removed from a repository.
 // The Webhook event name is "star".
 //
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 3f665ede..1fabd520 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -854,6 +854,22 @@ func (a *AppConfig) GetWebhookSecret() string {
 	return *a.WebhookSecret
 }
 
+// GetFrom returns the From field if it's non-nil, zero value otherwise.
+func (a *ArchivedAt) GetFrom() Timestamp {
+	if a == nil || a.From == nil {
+		return Timestamp{}
+	}
+	return *a.From
+}
+
+// GetTo returns the To field if it's non-nil, zero value otherwise.
+func (a *ArchivedAt) GetTo() Timestamp {
+	if a == nil || a.To == nil {
+		return Timestamp{}
+	}
+	return *a.To
+}
+
 // GetArchiveDownloadURL returns the ArchiveDownloadURL field if it's non-nil, zero value otherwise.
 func (a *Artifact) GetArchiveDownloadURL() string {
 	if a == nil || a.ArchiveDownloadURL == nil {
@@ -14374,6 +14390,286 @@ func (p *ProjectPermissionLevel) GetUser() *User {
 	return p.User
 }
 
+// GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetClosedAt() Timestamp {
+	if p == nil || p.ClosedAt == nil {
+		return Timestamp{}
+	}
+	return *p.ClosedAt
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (p *ProjectsV2) GetCreator() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Creator
+}
+
+// GetDeletedAt returns the DeletedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetDeletedAt() Timestamp {
+	if p == nil || p.DeletedAt == nil {
+		return Timestamp{}
+	}
+	return *p.DeletedAt
+}
+
+// GetDeletedBy returns the DeletedBy field.
+func (p *ProjectsV2) GetDeletedBy() *User {
+	if p == nil {
+		return nil
+	}
+	return p.DeletedBy
+}
+
+// GetDescription returns the Description field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetDescription() string {
+	if p == nil || p.Description == nil {
+		return ""
+	}
+	return *p.Description
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
+// GetNumber returns the Number field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetNumber() int {
+	if p == nil || p.Number == nil {
+		return 0
+	}
+	return *p.Number
+}
+
+// GetOwner returns the Owner field.
+func (p *ProjectsV2) GetOwner() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Owner
+}
+
+// GetPublic returns the Public field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetPublic() bool {
+	if p == nil || p.Public == nil {
+		return false
+	}
+	return *p.Public
+}
+
+// GetShortDescription returns the ShortDescription field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetShortDescription() string {
+	if p == nil || p.ShortDescription == nil {
+		return ""
+	}
+	return *p.ShortDescription
+}
+
+// GetTitle returns the Title field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetTitle() string {
+	if p == nil || p.Title == nil {
+		return ""
+	}
+	return *p.Title
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectsV2) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Event) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetInstallation returns the Installation field.
+func (p *ProjectV2Event) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrg returns the Org field.
+func (p *ProjectV2Event) GetOrg() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Org
+}
+
+// GetProjectsV2 returns the ProjectsV2 field.
+func (p *ProjectV2Event) GetProjectsV2() *ProjectsV2 {
+	if p == nil {
+		return nil
+	}
+	return p.ProjectsV2
+}
+
+// GetSender returns the Sender field.
+func (p *ProjectV2Event) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
+// GetArchivedAt returns the ArchivedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Item) GetArchivedAt() Timestamp {
+	if p == nil || p.ArchivedAt == nil {
+		return Timestamp{}
+	}
+	return *p.ArchivedAt
+}
+
+// GetContentNodeID returns the ContentNodeID field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Item) GetContentNodeID() string {
+	if p == nil || p.ContentNodeID == nil {
+		return ""
+	}
+	return *p.ContentNodeID
+}
+
+// GetContentType returns the ContentType field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Item) GetContentType() string {
+	if p == nil || p.ContentType == nil {
+		return ""
+	}
+	return *p.ContentType
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Item) GetCreatedAt() Timestamp {
+	if p == nil || p.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.CreatedAt
+}
+
+// GetCreator returns the Creator field.
+func (p *ProjectV2Item) GetCreator() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Creator
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Item) GetID() int64 {
+	if p == nil || p.ID == nil {
+		return 0
+	}
+	return *p.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Item) GetNodeID() string {
+	if p == nil || p.NodeID == nil {
+		return ""
+	}
+	return *p.NodeID
+}
+
+// GetProjectNodeID returns the ProjectNodeID field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Item) GetProjectNodeID() string {
+	if p == nil || p.ProjectNodeID == nil {
+		return ""
+	}
+	return *p.ProjectNodeID
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (p *ProjectV2Item) GetUpdatedAt() Timestamp {
+	if p == nil || p.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *p.UpdatedAt
+}
+
+// GetArchivedAt returns the ArchivedAt field.
+func (p *ProjectV2ItemChange) GetArchivedAt() *ArchivedAt {
+	if p == nil {
+		return nil
+	}
+	return p.ArchivedAt
+}
+
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (p *ProjectV2ItemEvent) GetAction() string {
+	if p == nil || p.Action == nil {
+		return ""
+	}
+	return *p.Action
+}
+
+// GetChanges returns the Changes field.
+func (p *ProjectV2ItemEvent) GetChanges() *ProjectV2ItemChange {
+	if p == nil {
+		return nil
+	}
+	return p.Changes
+}
+
+// GetInstallation returns the Installation field.
+func (p *ProjectV2ItemEvent) GetInstallation() *Installation {
+	if p == nil {
+		return nil
+	}
+	return p.Installation
+}
+
+// GetOrg returns the Org field.
+func (p *ProjectV2ItemEvent) GetOrg() *Organization {
+	if p == nil {
+		return nil
+	}
+	return p.Org
+}
+
+// GetProjectV2Item returns the ProjectV2Item field.
+func (p *ProjectV2ItemEvent) GetProjectV2Item() *ProjectV2Item {
+	if p == nil {
+		return nil
+	}
+	return p.ProjectV2Item
+}
+
+// GetSender returns the Sender field.
+func (p *ProjectV2ItemEvent) GetSender() *User {
+	if p == nil {
+		return nil
+	}
+	return p.Sender
+}
+
 // GetAllowDeletions returns the AllowDeletions field.
 func (p *Protection) GetAllowDeletions() *AllowDeletions {
 	if p == nil {
@@ -20270,6 +20566,70 @@ func (s *SecurityAndAnalysis) GetSecretScanningPushProtection() *SecretScanningP
 	return s.SecretScanningPushProtection
 }
 
+// GetFrom returns the From field.
+func (s *SecurityAndAnalysisChange) GetFrom() *SecurityAndAnalysisChangeFrom {
+	if s == nil {
+		return nil
+	}
+	return s.From
+}
+
+// GetSecurityAndAnalysis returns the SecurityAndAnalysis field.
+func (s *SecurityAndAnalysisChangeFrom) GetSecurityAndAnalysis() *SecurityAndAnalysis {
+	if s == nil {
+		return nil
+	}
+	return s.SecurityAndAnalysis
+}
+
+// GetChanges returns the Changes field.
+func (s *SecurityAndAnalysisEvent) GetChanges() *SecurityAndAnalysisChange {
+	if s == nil {
+		return nil
+	}
+	return s.Changes
+}
+
+// GetEnterprise returns the Enterprise field.
+func (s *SecurityAndAnalysisEvent) GetEnterprise() *Enterprise {
+	if s == nil {
+		return nil
+	}
+	return s.Enterprise
+}
+
+// GetInstallation returns the Installation field.
+func (s *SecurityAndAnalysisEvent) GetInstallation() *Installation {
+	if s == nil {
+		return nil
+	}
+	return s.Installation
+}
+
+// GetOrganization returns the Organization field.
+func (s *SecurityAndAnalysisEvent) GetOrganization() *Organization {
+	if s == nil {
+		return nil
+	}
+	return s.Organization
+}
+
+// GetRepository returns the Repository field.
+func (s *SecurityAndAnalysisEvent) GetRepository() *Repository {
+	if s == nil {
+		return nil
+	}
+	return s.Repository
+}
+
+// GetSender returns the Sender field.
+func (s *SecurityAndAnalysisEvent) GetSender() *User {
+	if s == nil {
+		return nil
+	}
+	return s.Sender
+}
+
 // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise.
 func (s *SelectedReposList) GetTotalCount() int {
 	if s == nil || s.TotalCount == nil {
diff --git a/github/messages.go b/github/messages.go
index 929587d3..e15442e5 100644
--- a/github/messages.go
+++ b/github/messages.go
@@ -82,6 +82,8 @@ var (
 		"project":                        "ProjectEvent",
 		"project_card":                   "ProjectCardEvent",
 		"project_column":                 "ProjectColumnEvent",
+		"projects_v2":                    "ProjectV2Event",
+		"projects_v2_item":               "ProjectV2ItemEvent",
 		"public":                         "PublicEvent",
 		"pull_request":                   "PullRequestEvent",
 		"pull_request_review":            "PullRequestReviewEvent",
@@ -96,6 +98,7 @@ var (
 		"release":                        "ReleaseEvent",
 		"secret_scanning_alert":          "SecretScanningAlertEvent",
 		"security_advisory":              "SecurityAdvisoryEvent",
+		"security_and_analysis":          "SecurityAndAnalysisEvent",
 		"star":                           "StarEvent",
 		"status":                         "StatusEvent",
 		"team":                           "TeamEvent",
diff --git a/scrape/scrape.go b/scrape/scrape.go
index c3be9af1..dc7aa88f 100644
--- a/scrape/scrape.go
+++ b/scrape/scrape.go
@@ -97,15 +97,17 @@ func (c *Client) get(urlStr string, a ...interface{}) (*goquery.Document, error)
 	if err != nil {
 		return nil, fmt.Errorf("error parsing URL: %q: %v", urlStr, err)
 	}
+
 	resp, err := c.Client.Get(u.String())
 	if err != nil {
 		return nil, fmt.Errorf("error fetching url %q: %v", u, err)
 	}
+	defer resp.Body.Close()
+
 	if resp.StatusCode == http.StatusNotFound {
 		return nil, fmt.Errorf("received %v response fetching URL %q", resp.StatusCode, u)
 	}
 
-	defer resp.Body.Close()
 	doc, err := goquery.NewDocumentFromReader(resp.Body)
 	if err != nil {
 		return nil, fmt.Errorf("error parsing response: %v", err)


Test patch:
diff --git a/github/event_types_test.go b/github/event_types_test.go
index 8d6a8b95..c1cb4d96 100644
--- a/github/event_types_test.go
+++ b/github/event_types_test.go
@@ -14092,6 +14092,396 @@ func TestProjectColumnEvent_Marshal(t *testing.T) {
 	testJSONMarshal(t, u, want)
 }
 
+func TestProjectV2Event_Marshal(t *testing.T) {
+	testJSONMarshal(t, &ProjectV2Event{}, "{}")
+
+	u := &ProjectV2Event{
+		Action: String("a"),
+		ProjectsV2: &ProjectsV2{
+			ID:     Int64(1),
+			NodeID: String("nid"),
+			Owner: &User{
+				Login:     String("l"),
+				ID:        Int64(1),
+				NodeID:    String("n"),
+				URL:       String("u"),
+				ReposURL:  String("r"),
+				EventsURL: String("e"),
+				AvatarURL: String("a"),
+			},
+			Creator: &User{
+				Login:     String("l"),
+				ID:        Int64(1),
+				NodeID:    String("n"),
+				URL:       String("u"),
+				ReposURL:  String("r"),
+				EventsURL: String("e"),
+				AvatarURL: String("a"),
+			},
+			Title:            String("t"),
+			Description:      String("d"),
+			Public:           Bool(true),
+			ClosedAt:         &Timestamp{referenceTime},
+			CreatedAt:        &Timestamp{referenceTime},
+			UpdatedAt:        &Timestamp{referenceTime},
+			DeletedAt:        &Timestamp{referenceTime},
+			Number:           Int(1),
+			ShortDescription: String("sd"),
+			DeletedBy: &User{
+				Login:     String("l"),
+				ID:        Int64(1),
+				NodeID:    String("n"),
+				URL:       String("u"),
+				ReposURL:  String("r"),
+				EventsURL: String("e"),
+				AvatarURL: String("a"),
+			},
+		},
+		Org: &Organization{
+			BillingEmail:                         String("be"),
+			Blog:                                 String("b"),
+			Company:                              String("c"),
+			Email:                                String("e"),
+			TwitterUsername:                      String("tu"),
+			Location:                             String("loc"),
+			Name:                                 String("n"),
+			Description:                          String("d"),
+			IsVerified:                           Bool(true),
+			HasOrganizationProjects:              Bool(true),
+			HasRepositoryProjects:                Bool(true),
+			DefaultRepoPermission:                String("drp"),
+			MembersCanCreateRepos:                Bool(true),
+			MembersCanCreateInternalRepos:        Bool(true),
+			MembersCanCreatePrivateRepos:         Bool(true),
+			MembersCanCreatePublicRepos:          Bool(false),
+			MembersAllowedRepositoryCreationType: String("marct"),
+			MembersCanCreatePages:                Bool(true),
+			MembersCanCreatePublicPages:          Bool(false),
+			MembersCanCreatePrivatePages:         Bool(true),
+		},
+		Sender: &User{
+			Login:     String("l"),
+			ID:        Int64(1),
+			NodeID:    String("n"),
+			URL:       String("u"),
+			ReposURL:  String("r"),
+			EventsURL: String("e"),
+			AvatarURL: String("a"),
+		},
+		Installation: &Installation{
+			ID:       Int64(1),
+			NodeID:   String("nid"),
+			AppID:    Int64(1),
+			AppSlug:  String("as"),
+			TargetID: Int64(1),
+			Account: &User{
+				Login:           String("l"),
+				ID:              Int64(1),
+				URL:             String("u"),
+				AvatarURL:       String("a"),
+				GravatarID:      String("g"),
+				Name:            String("n"),
+				Company:         String("c"),
+				Blog:            String("b"),
+				Location:        String("l"),
+				Email:           String("e"),
+				Hireable:        Bool(true),
+				Bio:             String("b"),
+				TwitterUsername: String("t"),
+				PublicRepos:     Int(1),
+				Followers:       Int(1),
+				Following:       Int(1),
+				CreatedAt:       &Timestamp{referenceTime},
+				SuspendedAt:     &Timestamp{referenceTime},
+			},
+		},
+	}
+
+	want := `{
+		"action": "a",
+		"projects_v2": {
+			"id": 1,
+			"node_id": "nid",
+			"owner": {
+				"login": "l",
+				"id": 1,
+				"node_id": "n",
+				"avatar_url": "a",
+				"url": "u",
+				"events_url": "e",
+				"repos_url": "r"
+			},
+			"creator": {
+				"login": "l",
+				"id": 1,
+				"node_id": "n",
+				"avatar_url": "a",
+				"url": "u",
+				"events_url": "e",
+				"repos_url": "r"
+			},
+			"title": "t",
+			"description": "d",
+			"public": true,
+			"closed_at": ` + referenceTimeStr + `,
+			"created_at": ` + referenceTimeStr + `,
+			"updated_at": ` + referenceTimeStr + `,
+			"deleted_at": ` + referenceTimeStr + `,
+			"number": 1,
+			"short_description": "sd",
+			"deleted_by": {
+				"login": "l",
+				"id": 1,
+				"node_id": "n",
+				"avatar_url": "a",
+				"url": "u",
+				"events_url": "e",
+				"repos_url": "r"
+			}
+		},
+		"organization": {
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "loc",
+			"email": "e",
+			"twitter_username": "tu",
+			"description": "d",
+			"billing_email": "be",
+			"is_verified": true,
+			"has_organization_projects": true,
+			"has_repository_projects": true,
+			"default_repository_permission": "drp",
+			"members_can_create_repositories": true,
+			"members_can_create_public_repositories": false,
+			"members_can_create_private_repositories": true,
+			"members_can_create_internal_repositories": true,
+			"members_allowed_repository_creation_type": "marct",
+			"members_can_create_pages": true,
+			"members_can_create_public_pages": false,
+			"members_can_create_private_pages": true
+		},
+		"sender": {
+			"login": "l",
+			"id": 1,
+			"node_id": "n",
+			"avatar_url": "a",
+			"url": "u",
+			"events_url": "e",
+			"repos_url": "r"
+		},
+		"installation": {
+			"id": 1,
+			"node_id": "nid",
+			"app_id": 1,
+			"app_slug": "as",
+			"target_id": 1,
+			"account": {
+				"login": "l",
+				"id": 1,
+				"avatar_url": "a",
+				"gravatar_id": "g",
+				"name": "n",
+				"company": "c",
+				"blog": "b",
+				"location": "l",
+				"email": "e",
+				"hireable": true,
+				"bio": "b",
+				"twitter_username": "t",
+				"public_repos": 1,
+				"followers": 1,
+				"following": 1,
+				"created_at": ` + referenceTimeStr + `,
+				"suspended_at": ` + referenceTimeStr + `,
+				"url": "u"
+			}
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestProjectV2ItemEvent_Marshal(t *testing.T) {
+	testJSONMarshal(t, &ProjectV2ItemEvent{}, "{}")
+
+	u := &ProjectV2ItemEvent{
+		Action: String("a"),
+		Changes: &ProjectV2ItemChange{
+			ArchivedAt: &ArchivedAt{
+				From: &Timestamp{referenceTime},
+				To:   &Timestamp{referenceTime},
+			},
+		},
+		ProjectV2Item: &ProjectV2Item{
+			ID:            Int64(1),
+			NodeID:        String("nid"),
+			ProjectNodeID: String("pnid"),
+			ContentNodeID: String("cnid"),
+			ContentType:   String("ct"),
+			Creator: &User{
+				Login:     String("l"),
+				ID:        Int64(1),
+				NodeID:    String("n"),
+				URL:       String("u"),
+				ReposURL:  String("r"),
+				EventsURL: String("e"),
+				AvatarURL: String("a"),
+			},
+			CreatedAt:  &Timestamp{referenceTime},
+			UpdatedAt:  &Timestamp{referenceTime},
+			ArchivedAt: &Timestamp{referenceTime},
+		},
+		Org: &Organization{
+			BillingEmail:                         String("be"),
+			Blog:                                 String("b"),
+			Company:                              String("c"),
+			Email:                                String("e"),
+			TwitterUsername:                      String("tu"),
+			Location:                             String("loc"),
+			Name:                                 String("n"),
+			Description:                          String("d"),
+			IsVerified:                           Bool(true),
+			HasOrganizationProjects:              Bool(true),
+			HasRepositoryProjects:                Bool(true),
+			DefaultRepoPermission:                String("drp"),
+			MembersCanCreateRepos:                Bool(true),
+			MembersCanCreateInternalRepos:        Bool(true),
+			MembersCanCreatePrivateRepos:         Bool(true),
+			MembersCanCreatePublicRepos:          Bool(false),
+			MembersAllowedRepositoryCreationType: String("marct"),
+			MembersCanCreatePages:                Bool(true),
+			MembersCanCreatePublicPages:          Bool(false),
+			MembersCanCreatePrivatePages:         Bool(true),
+		},
+		Sender: &User{
+			Login:     String("l"),
+			ID:        Int64(1),
+			NodeID:    String("n"),
+			URL:       String("u"),
+			ReposURL:  String("r"),
+			EventsURL: String("e"),
+			AvatarURL: String("a"),
+		},
+		Installation: &Installation{
+			ID:       Int64(1),
+			NodeID:   String("nid"),
+			AppID:    Int64(1),
+			AppSlug:  String("as"),
+			TargetID: Int64(1),
+			Account: &User{
+				Login:           String("l"),
+				ID:              Int64(1),
+				URL:             String("u"),
+				AvatarURL:       String("a"),
+				GravatarID:      String("g"),
+				Name:            String("n"),
+				Company:         String("c"),
+				Blog:            String("b"),
+				Location:        String("l"),
+				Email:           String("e"),
+				Hireable:        Bool(true),
+				Bio:             String("b"),
+				TwitterUsername: String("t"),
+				PublicRepos:     Int(1),
+				Followers:       Int(1),
+				Following:       Int(1),
+				CreatedAt:       &Timestamp{referenceTime},
+				SuspendedAt:     &Timestamp{referenceTime},
+			},
+		},
+	}
+
+	want := `{
+		"action":  "a",
+		"changes": {
+			"archived_at": {
+				"from": ` + referenceTimeStr + `,
+				"to": ` + referenceTimeStr + `
+			}
+		},
+		"projects_v2_item": {
+			"id": 1,
+			"node_id": "nid",
+			"project_node_id": "pnid",
+			"content_node_id": "cnid",
+			"content_type": "ct",
+			"creator":  {
+				"login": "l",
+				"id": 1,
+				"node_id": "n",
+				"avatar_url": "a",
+				"url": "u",
+				"events_url": "e",
+				"repos_url": "r"
+			},
+			"created_at": ` + referenceTimeStr + `,
+			"updated_at": ` + referenceTimeStr + `,
+			"archived_at": ` + referenceTimeStr + `
+		},
+		"organization": {
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "loc",
+			"email": "e",
+			"twitter_username": "tu",
+			"description": "d",
+			"billing_email": "be",
+			"is_verified": true,
+			"has_organization_projects": true,
+			"has_repository_projects": true,
+			"default_repository_permission": "drp",
+			"members_can_create_repositories": true,
+			"members_can_create_public_repositories": false,
+			"members_can_create_private_repositories": true,
+			"members_can_create_internal_repositories": true,
+			"members_allowed_repository_creation_type": "marct",
+			"members_can_create_pages": true,
+			"members_can_create_public_pages": false,
+			"members_can_create_private_pages": true
+		},
+		"sender": {
+			"login": "l",
+			"id": 1,
+			"node_id": "n",
+			"avatar_url": "a",
+			"url": "u",
+			"events_url": "e",
+			"repos_url": "r"
+		},
+		"installation": {
+			"id": 1,
+			"node_id": "nid",
+			"app_id": 1,
+			"app_slug": "as",
+			"target_id": 1,
+			"account": {
+				"login": "l",
+				"id": 1,
+				"avatar_url": "a",
+				"gravatar_id": "g",
+				"name": "n",
+				"company": "c",
+				"blog": "b",
+				"location": "l",
+				"email": "e",
+				"hireable": true,
+				"bio": "b",
+				"twitter_username": "t",
+				"public_repos": 1,
+				"followers": 1,
+				"following": 1,
+				"created_at": ` + referenceTimeStr + `,
+				"suspended_at": ` + referenceTimeStr + `,
+				"url": "u"
+			}
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
 func TestPullRequestEvent_Marshal(t *testing.T) {
 	testJSONMarshal(t, &PullRequestEvent{}, "{}")
 
@@ -14732,14 +15122,321 @@ func TestPullRequestReviewThreadEvent_Marshal(t *testing.T) {
 	u := &PullRequestReviewThreadEvent{
 		Action:      String("a"),
 		PullRequest: &PullRequest{ID: Int64(1)},
-		Thread: &PullRequestThread{
-			Comments: []*PullRequestComment{{ID: Int64(1)}, {ID: Int64(2)}},
+		Thread: &PullRequestThread{
+			Comments: []*PullRequestComment{{ID: Int64(1)}, {ID: Int64(2)}},
+		},
+		Repo: &Repository{
+			ID:   Int64(1),
+			URL:  String("s"),
+			Name: String("n"),
+		},
+		Sender: &User{
+			Login:     String("l"),
+			ID:        Int64(1),
+			NodeID:    String("n"),
+			URL:       String("u"),
+			ReposURL:  String("r"),
+			EventsURL: String("e"),
+			AvatarURL: String("a"),
+		},
+		Installation: &Installation{
+			ID:       Int64(1),
+			NodeID:   String("nid"),
+			AppID:    Int64(1),
+			AppSlug:  String("as"),
+			TargetID: Int64(1),
+			Account: &User{
+				Login:           String("l"),
+				ID:              Int64(1),
+				URL:             String("u"),
+				AvatarURL:       String("a"),
+				GravatarID:      String("g"),
+				Name:            String("n"),
+				Company:         String("c"),
+				Blog:            String("b"),
+				Location:        String("l"),
+				Email:           String("e"),
+				Hireable:        Bool(true),
+				Bio:             String("b"),
+				TwitterUsername: String("t"),
+				PublicRepos:     Int(1),
+				Followers:       Int(1),
+				Following:       Int(1),
+				CreatedAt:       &Timestamp{referenceTime},
+				SuspendedAt:     &Timestamp{referenceTime},
+			},
+			AccessTokensURL:     String("atu"),
+			RepositoriesURL:     String("ru"),
+			HTMLURL:             String("hu"),
+			TargetType:          String("tt"),
+			SingleFileName:      String("sfn"),
+			RepositorySelection: String("rs"),
+			Events:              []string{"e"},
+			SingleFilePaths:     []string{"s"},
+			Permissions: &InstallationPermissions{
+				Actions:                       String("a"),
+				Administration:                String("ad"),
+				Checks:                        String("c"),
+				Contents:                      String("co"),
+				ContentReferences:             String("cr"),
+				Deployments:                   String("d"),
+				Environments:                  String("e"),
+				Issues:                        String("i"),
+				Metadata:                      String("md"),
+				Members:                       String("m"),
+				OrganizationAdministration:    String("oa"),
+				OrganizationHooks:             String("oh"),
+				OrganizationPlan:              String("op"),
+				OrganizationPreReceiveHooks:   String("opr"),
+				OrganizationProjects:          String("op"),
+				OrganizationSecrets:           String("os"),
+				OrganizationSelfHostedRunners: String("osh"),
+				OrganizationUserBlocking:      String("oub"),
+				Packages:                      String("pkg"),
+				Pages:                         String("pg"),
+				PullRequests:                  String("pr"),
+				RepositoryHooks:               String("rh"),
+				RepositoryProjects:            String("rp"),
+				RepositoryPreReceiveHooks:     String("rprh"),
+				Secrets:                       String("s"),
+				SecretScanningAlerts:          String("ssa"),
+				SecurityEvents:                String("se"),
+				SingleFile:                    String("sf"),
+				Statuses:                      String("s"),
+				TeamDiscussions:               String("td"),
+				VulnerabilityAlerts:           String("va"),
+				Workflows:                     String("w"),
+			},
+			CreatedAt:              &Timestamp{referenceTime},
+			UpdatedAt:              &Timestamp{referenceTime},
+			HasMultipleSingleFiles: Bool(false),
+			SuspendedBy: &User{
+				Login:           String("l"),
+				ID:              Int64(1),
+				URL:             String("u"),
+				AvatarURL:       String("a"),
+				GravatarID:      String("g"),
+				Name:            String("n"),
+				Company:         String("c"),
+				Blog:            String("b"),
+				Location:        String("l"),
+				Email:           String("e"),
+				Hireable:        Bool(true),
+				Bio:             String("b"),
+				TwitterUsername: String("t"),
+				PublicRepos:     Int(1),
+				Followers:       Int(1),
+				Following:       Int(1),
+				CreatedAt:       &Timestamp{referenceTime},
+				SuspendedAt:     &Timestamp{referenceTime},
+			},
+			SuspendedAt: &Timestamp{referenceTime},
+		},
+	}
+
+	want := `{
+		"action": "a",
+		"pull_request": {
+			"id": 1
+		},
+		"thread": {
+			"comments": [
+				{
+					"id": 1
+				},
+				{
+					"id": 2
+				}
+			]
+		},
+		"repository": {
+			"id": 1,
+			"name": "n",
+			"url": "s"
+		},
+		"sender": {
+			"login": "l",
+			"id": 1,
+			"node_id": "n",
+			"avatar_url": "a",
+			"url": "u",
+			"events_url": "e",
+			"repos_url": "r"
+		},
+		"installation": {
+			"id": 1,
+			"node_id": "nid",
+			"app_id": 1,
+			"app_slug": "as",
+			"target_id": 1,
+			"account": {
+				"login": "l",
+				"id": 1,
+				"avatar_url": "a",
+				"gravatar_id": "g",
+				"name": "n",
+				"company": "c",
+				"blog": "b",
+				"location": "l",
+				"email": "e",
+				"hireable": true,
+				"bio": "b",
+				"twitter_username": "t",
+				"public_repos": 1,
+				"followers": 1,
+				"following": 1,
+				"created_at": ` + referenceTimeStr + `,
+				"suspended_at": ` + referenceTimeStr + `,
+				"url": "u"
+			},
+			"access_tokens_url": "atu",
+			"repositories_url": "ru",
+			"html_url": "hu",
+			"target_type": "tt",
+			"single_file_name": "sfn",
+			"repository_selection": "rs",
+			"events": [
+				"e"
+			],
+			"single_file_paths": [
+				"s"
+			],
+			"permissions": {
+				"actions": "a",
+				"administration": "ad",
+				"checks": "c",
+				"contents": "co",
+				"content_references": "cr",
+				"deployments": "d",
+				"environments": "e",
+				"issues": "i",
+				"metadata": "md",
+				"members": "m",
+				"organization_administration": "oa",
+				"organization_hooks": "oh",
+				"organization_plan": "op",
+				"organization_pre_receive_hooks": "opr",
+				"organization_projects": "op",
+				"organization_secrets": "os",
+				"organization_self_hosted_runners": "osh",
+				"organization_user_blocking": "oub",
+				"packages": "pkg",
+				"pages": "pg",
+				"pull_requests": "pr",
+				"repository_hooks": "rh",
+				"repository_projects": "rp",
+				"repository_pre_receive_hooks": "rprh",
+				"secrets": "s",
+				"secret_scanning_alerts": "ssa",
+				"security_events": "se",
+				"single_file": "sf",
+				"statuses": "s",
+				"team_discussions": "td",
+				"vulnerability_alerts": "va",
+				"workflows": "w"
+			},
+			"created_at": ` + referenceTimeStr + `,
+			"updated_at": ` + referenceTimeStr + `,
+			"has_multiple_single_files": false,
+			"suspended_by": {
+				"login": "l",
+				"id": 1,
+				"avatar_url": "a",
+				"gravatar_id": "g",
+				"name": "n",
+				"company": "c",
+				"blog": "b",
+				"location": "l",
+				"email": "e",
+				"hireable": true,
+				"bio": "b",
+				"twitter_username": "t",
+				"public_repos": 1,
+				"followers": 1,
+				"following": 1,
+				"created_at": ` + referenceTimeStr + `,
+				"suspended_at": ` + referenceTimeStr + `,
+				"url": "u"
+			},
+			"suspended_at": ` + referenceTimeStr + `
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestPullRequestTargetEvent_Marshal(t *testing.T) {
+	testJSONMarshal(t, &PullRequestTargetEvent{}, "{}")
+
+	u := &PullRequestTargetEvent{
+		Action: String("a"),
+		Assignee: &User{
+			Login:     String("l"),
+			ID:        Int64(1),
+			NodeID:    String("n"),
+			URL:       String("u"),
+			ReposURL:  String("r"),
+			EventsURL: String("e"),
+			AvatarURL: String("a"),
+		},
+		Number:      Int(1),
+		PullRequest: &PullRequest{ID: Int64(1)},
+		Changes: &EditChange{
+			Title: &EditTitle{
+				From: String("TitleFrom"),
+			},
+			Body: &EditBody{
+				From: String("BodyFrom"),
+			},
+			Base: &EditBase{
+				Ref: &EditRef{
+					From: String("BaseRefFrom"),
+				},
+				SHA: &EditSHA{
+					From: String("BaseSHAFrom"),
+				},
+			},
+		},
+		RequestedReviewer: &User{
+			Login:     String("l"),
+			ID:        Int64(1),
+			NodeID:    String("n"),
+			URL:       String("u"),
+			ReposURL:  String("r"),
+			EventsURL: String("e"),
+			AvatarURL: String("a"),
 		},
+		RequestedTeam: &Team{ID: Int64(1)},
+		Label:         &Label{ID: Int64(1)},
+		Before:        String("before"),
+		After:         String("after"),
 		Repo: &Repository{
 			ID:   Int64(1),
 			URL:  String("s"),
 			Name: String("n"),
 		},
+		Organization: &Organization{
+			BillingEmail:                         String("be"),
+			Blog:                                 String("b"),
+			Company:                              String("c"),
+			Email:                                String("e"),
+			TwitterUsername:                      String("tu"),
+			Location:                             String("loc"),
+			Name:                                 String("n"),
+			Description:                          String("d"),
+			IsVerified:                           Bool(true),
+			HasOrganizationProjects:              Bool(true),
+			HasRepositoryProjects:                Bool(true),
+			DefaultRepoPermission:                String("drp"),
+			MembersCanCreateRepos:                Bool(true),
+			MembersCanCreateInternalRepos:        Bool(true),
+			MembersCanCreatePrivateRepos:         Bool(true),
+			MembersCanCreatePublicRepos:          Bool(false),
+			MembersAllowedRepositoryCreationType: String("marct"),
+			MembersCanCreatePages:                Bool(true),
+			MembersCanCreatePublicPages:          Bool(false),
+			MembersCanCreatePrivatePages:         Bool(true),
+		},
 		Sender: &User{
 			Login:     String("l"),
 			ID:        Int64(1),
@@ -14846,18 +15543,46 @@ func TestPullRequestReviewThreadEvent_Marshal(t *testing.T) {
 
 	want := `{
 		"action": "a",
+		"assignee": {
+			"login": "l",
+			"id": 1,
+			"node_id": "n",
+			"avatar_url": "a",
+			"url": "u",
+			"events_url": "e",
+			"repos_url": "r"
+		},
+		"number": 1,
 		"pull_request": {
 			"id": 1
 		},
-		"thread": {
-			"comments": [
-				{
-					"id": 1
+		"changes": {
+			"title": {
+				"from": "TitleFrom"
+			},
+			"body": {
+				"from": "BodyFrom"
+			},
+			"base": {
+				"ref": {
+					"from": "BaseRefFrom"
 				},
-				{
-					"id": 2
+				"sha": {
+					"from": "BaseSHAFrom"
 				}
-			]
+			}
+		},
+		"requested_reviewer": {
+			"login": "l",
+			"id": 1,
+			"node_id": "n",
+			"avatar_url": "a",
+			"url": "u",
+			"events_url": "e",
+			"repos_url": "r"
+		},
+		"requested_team": {
+			"id": 1
 		},
 		"repository": {
 			"id": 1,
@@ -14969,57 +15694,121 @@ func TestPullRequestReviewThreadEvent_Marshal(t *testing.T) {
 				"url": "u"
 			},
 			"suspended_at": ` + referenceTimeStr + `
-		}
+		},
+		"label": {
+			"id": 1
+		},
+		"organization": {
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "loc",
+			"email": "e",
+			"twitter_username": "tu",
+			"description": "d",
+			"billing_email": "be",
+			"is_verified": true,
+			"has_organization_projects": true,
+			"has_repository_projects": true,
+			"default_repository_permission": "drp",
+			"members_can_create_repositories": true,
+			"members_can_create_public_repositories": false,
+			"members_can_create_private_repositories": true,
+			"members_can_create_internal_repositories": true,
+			"members_allowed_repository_creation_type": "marct",
+			"members_can_create_pages": true,
+			"members_can_create_public_pages": false,
+			"members_can_create_private_pages": true
+		},
+		"before": "before",
+		"after": "after"
 	}`
 
 	testJSONMarshal(t, u, want)
 }
 
-func TestPullRequestTargetEvent_Marshal(t *testing.T) {
-	testJSONMarshal(t, &PullRequestTargetEvent{}, "{}")
+func TestRepositoryVulnerabilityAlertEvent_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RepositoryVulnerabilityAlertEvent{}, "{}")
 
-	u := &PullRequestTargetEvent{
+	u := &RepositoryVulnerabilityAlertEvent{
 		Action: String("a"),
-		Assignee: &User{
-			Login:     String("l"),
-			ID:        Int64(1),
-			NodeID:    String("n"),
-			URL:       String("u"),
-			ReposURL:  String("r"),
-			EventsURL: String("e"),
-			AvatarURL: String("a"),
-		},
-		Number:      Int(1),
-		PullRequest: &PullRequest{ID: Int64(1)},
-		Changes: &EditChange{
-			Title: &EditTitle{
-				From: String("TitleFrom"),
-			},
-			Body: &EditBody{
-				From: String("BodyFrom"),
+		Alert: &RepositoryVulnerabilityAlert{
+			ID:                  Int64(1),
+			AffectedRange:       String("ar"),
+			AffectedPackageName: String("apn"),
+			ExternalReference:   String("er"),
+			ExternalIdentifier:  String("ei"),
+			FixedIn:             String("fi"),
+			Dismisser: &User{
+				Login:     String("l"),
+				ID:        Int64(1),
+				NodeID:    String("n"),
+				URL:       String("u"),
+				ReposURL:  String("r"),
+				EventsURL: String("e"),
+				AvatarURL: String("a"),
 			},
-			Base: &EditBase{
-				Ref: &EditRef{
-					From: String("BaseRefFrom"),
-				},
-				SHA: &EditSHA{
-					From: String("BaseSHAFrom"),
-				},
+			DismissReason: String("dr"),
+			DismissedAt:   &Timestamp{referenceTime},
+		},
+		Repository: &Repository{
+			ID:   Int64(1),
+			URL:  String("s"),
+			Name: String("n"),
+		},
+	}
+
+	want := `{
+		"action": "a",
+		"alert": {
+			"id": 1,
+			"affected_range": "ar",
+			"affected_package_name": "apn",
+			"external_reference": "er",
+			"external_identifier": "ei",
+			"fixed_in": "fi",
+			"dismisser": {
+				"login": "l",
+				"id": 1,
+				"node_id": "n",
+				"avatar_url": "a",
+				"url": "u",
+				"events_url": "e",
+				"repos_url": "r"
 			},
+			"dismiss_reason": "dr",
+			"dismissed_at": ` + referenceTimeStr + `
 		},
-		RequestedReviewer: &User{
-			Login:     String("l"),
-			ID:        Int64(1),
-			NodeID:    String("n"),
-			URL:       String("u"),
-			ReposURL:  String("r"),
-			EventsURL: String("e"),
-			AvatarURL: String("a"),
+		"repository": {
+			"id": 1,
+			"name": "n",
+			"url": "s"
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestSecretScanningAlertEvent_Marshal(t *testing.T) {
+	testJSONMarshal(t, &SecretScanningAlertEvent{}, "{}")
+
+	u := &SecretScanningAlertEvent{
+		Action: String("a"),
+		Alert: &SecretScanningAlert{
+			Number:     Int(1),
+			SecretType: String("t"),
+			Resolution: String("r"),
+			ResolvedBy: &User{
+				Login:     String("l"),
+				ID:        Int64(1),
+				NodeID:    String("n"),
+				URL:       String("u"),
+				ReposURL:  String("r"),
+				EventsURL: String("e"),
+				AvatarURL: String("a"),
+			},
+			ResolvedAt: &Timestamp{referenceTime},
 		},
-		RequestedTeam: &Team{ID: Int64(1)},
-		Label:         &Label{ID: Int64(1)},
-		Before:        String("before"),
-		After:         String("after"),
 		Repo: &Repository{
 			ID:   Int64(1),
 			URL:  String("s"),
@@ -15047,6 +15836,18 @@ func TestPullRequestTargetEvent_Marshal(t *testing.T) {
 			MembersCanCreatePublicPages:          Bool(false),
 			MembersCanCreatePrivatePages:         Bool(true),
 		},
+		Enterprise: &Enterprise{
+			ID:          Int(1),
+			Slug:        String("s"),
+			Name:        String("n"),
+			NodeID:      String("nid"),
+			AvatarURL:   String("au"),
+			Description: String("d"),
+			WebsiteURL:  String("wu"),
+			HTMLURL:     String("hu"),
+			CreatedAt:   &Timestamp{referenceTime},
+			UpdatedAt:   &Timestamp{referenceTime},
+		},
 		Sender: &User{
 			Login:     String("l"),
 			ID:        Int64(1),
@@ -15153,51 +15954,59 @@ func TestPullRequestTargetEvent_Marshal(t *testing.T) {
 
 	want := `{
 		"action": "a",
-		"assignee": {
-			"login": "l",
-			"id": 1,
-			"node_id": "n",
-			"avatar_url": "a",
-			"url": "u",
-			"events_url": "e",
-			"repos_url": "r"
-		},
-		"number": 1,
-		"pull_request": {
-			"id": 1
-		},
-		"changes": {
-			"title": {
-				"from": "TitleFrom"
-			},
-			"body": {
-				"from": "BodyFrom"
+		"alert": {
+			"number": 1,
+			"secret_type": "t",
+			"resolution": "r",
+			"resolved_by": {
+				"login": "l",
+				"id": 1,
+				"node_id": "n",
+				"avatar_url": "a",
+				"url": "u",
+				"events_url": "e",
+				"repos_url": "r"
 			},
-			"base": {
-				"ref": {
-					"from": "BaseRefFrom"
-				},
-				"sha": {
-					"from": "BaseSHAFrom"
-				}
-			}
+			"resolved_at": ` + referenceTimeStr + `
 		},
-		"requested_reviewer": {
-			"login": "l",
+		"repository": {
 			"id": 1,
-			"node_id": "n",
-			"avatar_url": "a",
-			"url": "u",
-			"events_url": "e",
-			"repos_url": "r"
+			"name": "n",
+			"url": "s"
 		},
-		"requested_team": {
-			"id": 1
+        "organization": {
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "loc",
+			"email": "e",
+			"twitter_username": "tu",
+			"description": "d",
+			"billing_email": "be",
+			"is_verified": true,
+			"has_organization_projects": true,
+			"has_repository_projects": true,
+			"default_repository_permission": "drp",
+			"members_can_create_repositories": true,
+			"members_can_create_public_repositories": false,
+			"members_can_create_private_repositories": true,
+			"members_can_create_internal_repositories": true,
+			"members_allowed_repository_creation_type": "marct",
+			"members_can_create_pages": true,
+			"members_can_create_public_pages": false,
+			"members_can_create_private_pages": true
 		},
-		"repository": {
+        "enterprise": {
 			"id": 1,
+			"slug": "s",
 			"name": "n",
-			"url": "s"
+			"node_id": "nid",
+			"avatar_url": "au",
+			"description": "d",
+			"website_url": "wu",
+			"html_url": "hu",
+			"created_at": ` + referenceTimeStr + `,
+			"updated_at": ` + referenceTimeStr + `
 		},
 		"sender": {
 			"login": "l",
@@ -15208,7 +16017,7 @@ func TestPullRequestTargetEvent_Marshal(t *testing.T) {
 			"events_url": "e",
 			"repos_url": "r"
 		},
-		"installation": {
+        "installation": {
 			"id": 1,
 			"node_id": "nid",
 			"app_id": 1,
@@ -15304,147 +16113,112 @@ func TestPullRequestTargetEvent_Marshal(t *testing.T) {
 				"url": "u"
 			},
 			"suspended_at": ` + referenceTimeStr + `
-		},
-		"label": {
-			"id": 1
-		},
-		"organization": {
-			"name": "n",
-			"company": "c",
-			"blog": "b",
-			"location": "loc",
-			"email": "e",
-			"twitter_username": "tu",
-			"description": "d",
-			"billing_email": "be",
-			"is_verified": true,
-			"has_organization_projects": true,
-			"has_repository_projects": true,
-			"default_repository_permission": "drp",
-			"members_can_create_repositories": true,
-			"members_can_create_public_repositories": false,
-			"members_can_create_private_repositories": true,
-			"members_can_create_internal_repositories": true,
-			"members_allowed_repository_creation_type": "marct",
-			"members_can_create_pages": true,
-			"members_can_create_public_pages": false,
-			"members_can_create_private_pages": true
-		},
-		"before": "before",
-		"after": "after"
+		}
 	}`
 
 	testJSONMarshal(t, u, want)
 }
 
-func TestRepositoryVulnerabilityAlertEvent_Marshal(t *testing.T) {
-	testJSONMarshal(t, &RepositoryVulnerabilityAlertEvent{}, "{}")
-
-	u := &RepositoryVulnerabilityAlertEvent{
-		Action: String("a"),
-		Alert: &RepositoryVulnerabilityAlert{
-			ID:                  Int64(1),
-			AffectedRange:       String("ar"),
-			AffectedPackageName: String("apn"),
-			ExternalReference:   String("er"),
-			ExternalIdentifier:  String("ei"),
-			FixedIn:             String("fi"),
-			Dismisser: &User{
-				Login:     String("l"),
-				ID:        Int64(1),
-				NodeID:    String("n"),
-				URL:       String("u"),
-				ReposURL:  String("r"),
-				EventsURL: String("e"),
-				AvatarURL: String("a"),
+func TestSecurityAdvisoryEvent_Marshal(t *testing.T) {
+	testJSONMarshal(t, &SecurityAdvisoryEvent{}, "{}")
+	u := &SecurityAdvisoryEvent{
+		Action: String("published"),
+		SecurityAdvisory: &SecurityAdvisory{
+			GHSAID:      String("GHSA-rf4j-j272-some"),
+			Summary:     String("Siuuuuuuuuu"),
+			Description: String("desc"),
+			Severity:    String("moderate"),
+			Identifiers: []*AdvisoryIdentifier{
+				{
+					Value: String("GHSA-rf4j-j272-some"),
+					Type:  String("GHSA"),
+				},
+			},
+			References: []*AdvisoryReference{
+				{
+					URL: String("https://some-url"),
+				},
+			},
+			PublishedAt: &Timestamp{referenceTime},
+			UpdatedAt:   &Timestamp{referenceTime},
+			WithdrawnAt: nil,
+			Vulnerabilities: []*AdvisoryVulnerability{
+				{
+					Package: &VulnerabilityPackage{
+						Ecosystem: String("ucl"),
+						Name:      String("penaldo"),
+					},
+					Severity:               String("moderate"),
+					VulnerableVersionRange: String(">= 2.0.0, < 2.0.2"),
+					FirstPatchedVersion: &FirstPatchedVersion{
+						Identifier: String("2.0.2"),
+					},
+				},
 			},
-			DismissReason: String("dr"),
-			DismissedAt:   &Timestamp{referenceTime},
-		},
-		Repository: &Repository{
-			ID:   Int64(1),
-			URL:  String("s"),
-			Name: String("n"),
 		},
 	}
 
 	want := `{
-		"action": "a",
-		"alert": {
-			"id": 1,
-			"affected_range": "ar",
-			"affected_package_name": "apn",
-			"external_reference": "er",
-			"external_identifier": "ei",
-			"fixed_in": "fi",
-			"dismisser": {
-				"login": "l",
-				"id": 1,
-				"node_id": "n",
-				"avatar_url": "a",
-				"url": "u",
-				"events_url": "e",
-				"repos_url": "r"
-			},
-			"dismiss_reason": "dr",
-			"dismissed_at": ` + referenceTimeStr + `
-		},
-		"repository": {
-			"id": 1,
-			"name": "n",
-			"url": "s"
+		"action": "published",
+		"security_advisory": {
+		  "ghsa_id": "GHSA-rf4j-j272-some",
+		  "summary": "Siuuuuuuuuu",
+		  "description": "desc",
+		  "severity": "moderate",
+		  "identifiers": [
+			{
+			  "value": "GHSA-rf4j-j272-some",
+			  "type": "GHSA"
+			}
+		  ],
+		  "references": [
+			{
+			  "url": "https://some-url"
+			}
+		  ],
+		  "published_at": ` + referenceTimeStr + `,
+		  "updated_at": ` + referenceTimeStr + `,
+		  "withdrawn_at": null,
+		  "vulnerabilities": [
+			{
+			  "package": {
+				"ecosystem": "ucl",
+				"name": "penaldo"
+			  },
+			  "severity": "moderate",
+			  "vulnerable_version_range": ">= 2.0.0, < 2.0.2",
+			  "first_patched_version": {
+				"identifier": "2.0.2"
+			  }
+			}
+		  ]
 		}
-	}`
+	  }`
 
 	testJSONMarshal(t, u, want)
 }
 
-func TestSecretScanningAlertEvent_Marshal(t *testing.T) {
-	testJSONMarshal(t, &SecretScanningAlertEvent{}, "{}")
+func TestSecurityAndAnalysisEvent_Marshal(t *testing.T) {
+	testJSONMarshal(t, &SecurityAndAnalysisEvent{}, "{}")
 
-	u := &SecretScanningAlertEvent{
-		Action: String("a"),
-		Alert: &SecretScanningAlert{
-			Number:     Int(1),
-			SecretType: String("t"),
-			Resolution: String("r"),
-			ResolvedBy: &User{
-				Login:     String("l"),
-				ID:        Int64(1),
-				NodeID:    String("n"),
-				URL:       String("u"),
-				ReposURL:  String("r"),
-				EventsURL: String("e"),
-				AvatarURL: String("a"),
+	u := &SecurityAndAnalysisEvent{
+		Changes: &SecurityAndAnalysisChange{
+			From: &SecurityAndAnalysisChangeFrom{
+				SecurityAndAnalysis: &SecurityAndAnalysis{
+					AdvancedSecurity: &AdvancedSecurity{
+						Status: String("enabled"),
+					},
+					SecretScanning: &SecretScanning{
+						Status: String("enabled"),
+					},
+					SecretScanningPushProtection: &SecretScanningPushProtection{
+						Status: String("enabled"),
+					},
+					DependabotSecurityUpdates: &DependabotSecurityUpdates{
+						Status: String("enabled"),
+					},
+				},
 			},
-			ResolvedAt: &Timestamp{referenceTime},
-		},
-		Repo: &Repository{
-			ID:   Int64(1),
-			URL:  String("s"),
-			Name: String("n"),
-		},
-		Organization: &Organization{
-			BillingEmail:                         String("be"),
-			Blog:                                 String("b"),
-			Company:                              String("c"),
-			Email:                                String("e"),
-			TwitterUsername:                      String("tu"),
-			Location:                             String("loc"),
-			Name:                                 String("n"),
-			Description:                          String("d"),
-			IsVerified:                           Bool(true),
-			HasOrganizationProjects:              Bool(true),
-			HasRepositoryProjects:                Bool(true),
-			DefaultRepoPermission:                String("drp"),
-			MembersCanCreateRepos:                Bool(true),
-			MembersCanCreateInternalRepos:        Bool(true),
-			MembersCanCreatePrivateRepos:         Bool(true),
-			MembersCanCreatePublicRepos:          Bool(false),
-			MembersAllowedRepositoryCreationType: String("marct"),
-			MembersCanCreatePages:                Bool(true),
-			MembersCanCreatePublicPages:          Bool(false),
-			MembersCanCreatePrivatePages:         Bool(true),
 		},
 		Enterprise: &Enterprise{
 			ID:          Int(1),
@@ -15458,15 +16232,6 @@ func TestSecretScanningAlertEvent_Marshal(t *testing.T) {
 			CreatedAt:   &Timestamp{referenceTime},
 			UpdatedAt:   &Timestamp{referenceTime},
 		},
-		Sender: &User{
-			Login:     String("l"),
-			ID:        Int64(1),
-			NodeID:    String("n"),
-			URL:       String("u"),
-			ReposURL:  String("r"),
-			EventsURL: String("e"),
-			AvatarURL: String("a"),
-		},
 		Installation: &Installation{
 			ID:       Int64(1),
 			NodeID:   String("nid"),
@@ -15560,53 +16325,64 @@ func TestSecretScanningAlertEvent_Marshal(t *testing.T) {
 			},
 			SuspendedAt: &Timestamp{referenceTime},
 		},
+		Organization: &Organization{
+			BillingEmail:                         String("be"),
+			Blog:                                 String("b"),
+			Company:                              String("c"),
+			Email:                                String("e"),
+			TwitterUsername:                      String("tu"),
+			Location:                             String("loc"),
+			Name:                                 String("n"),
+			Description:                          String("d"),
+			IsVerified:                           Bool(true),
+			HasOrganizationProjects:              Bool(true),
+			HasRepositoryProjects:                Bool(true),
+			DefaultRepoPermission:                String("drp"),
+			MembersCanCreateRepos:                Bool(true),
+			MembersCanCreateInternalRepos:        Bool(true),
+			MembersCanCreatePrivateRepos:         Bool(true),
+			MembersCanCreatePublicRepos:          Bool(false),
+			MembersAllowedRepositoryCreationType: String("marct"),
+			MembersCanCreatePages:                Bool(true),
+			MembersCanCreatePublicPages:          Bool(false),
+			MembersCanCreatePrivatePages:         Bool(true),
+		},
+		Repository: &Repository{
+			ID:   Int64(1),
+			URL:  String("s"),
+			Name: String("n"),
+		},
+		Sender: &User{
+			Login:     String("l"),
+			ID:        Int64(1),
+			NodeID:    String("n"),
+			URL:       String("u"),
+			ReposURL:  String("r"),
+			EventsURL: String("e"),
+			AvatarURL: String("a"),
+		},
 	}
 
 	want := `{
-		"action": "a",
-		"alert": {
-			"number": 1,
-			"secret_type": "t",
-			"resolution": "r",
-			"resolved_by": {
-				"login": "l",
-				"id": 1,
-				"node_id": "n",
-				"avatar_url": "a",
-				"url": "u",
-				"events_url": "e",
-				"repos_url": "r"
-			},
-			"resolved_at": ` + referenceTimeStr + `
-		},
-		"repository": {
-			"id": 1,
-			"name": "n",
-			"url": "s"
-		},
-        "organization": {
-			"name": "n",
-			"company": "c",
-			"blog": "b",
-			"location": "loc",
-			"email": "e",
-			"twitter_username": "tu",
-			"description": "d",
-			"billing_email": "be",
-			"is_verified": true,
-			"has_organization_projects": true,
-			"has_repository_projects": true,
-			"default_repository_permission": "drp",
-			"members_can_create_repositories": true,
-			"members_can_create_public_repositories": false,
-			"members_can_create_private_repositories": true,
-			"members_can_create_internal_repositories": true,
-			"members_allowed_repository_creation_type": "marct",
-			"members_can_create_pages": true,
-			"members_can_create_public_pages": false,
-			"members_can_create_private_pages": true
+		"changes": {
+			"from": {
+				"security_and_analysis": {
+					"advanced_security": {
+						"status": "enabled"
+					},
+					"secret_scanning": {
+						"status": "enabled"
+					},
+					"secret_scanning_push_protection": {
+						"status": "enabled"
+					},
+					"dependabot_security_updates": {
+						"status": "enabled"
+					}
+				}
+			}
 		},
-        "enterprise": {
+		"enterprise": {
 			"id": 1,
 			"slug": "s",
 			"name": "n",
@@ -15618,16 +16394,7 @@ func TestSecretScanningAlertEvent_Marshal(t *testing.T) {
 			"created_at": ` + referenceTimeStr + `,
 			"updated_at": ` + referenceTimeStr + `
 		},
-		"sender": {
-			"login": "l",
-			"id": 1,
-			"node_id": "n",
-			"avatar_url": "a",
-			"url": "u",
-			"events_url": "e",
-			"repos_url": "r"
-		},
-        "installation": {
+		"installation": {
 			"id": 1,
 			"node_id": "nid",
 			"app_id": 1,
@@ -15723,87 +16490,45 @@ func TestSecretScanningAlertEvent_Marshal(t *testing.T) {
 				"url": "u"
 			},
 			"suspended_at": ` + referenceTimeStr + `
-		}
-	}`
-
-	testJSONMarshal(t, u, want)
-}
-
-func TestSecurityAdvisoryEvent_Marshal(t *testing.T) {
-	testJSONMarshal(t, &SecurityAdvisoryEvent{}, "{}")
-	u := &SecurityAdvisoryEvent{
-		Action: String("published"),
-		SecurityAdvisory: &SecurityAdvisory{
-			GHSAID:      String("GHSA-rf4j-j272-some"),
-			Summary:     String("Siuuuuuuuuu"),
-			Description: String("desc"),
-			Severity:    String("moderate"),
-			Identifiers: []*AdvisoryIdentifier{
-				{
-					Value: String("GHSA-rf4j-j272-some"),
-					Type:  String("GHSA"),
-				},
-			},
-			References: []*AdvisoryReference{
-				{
-					URL: String("https://some-url"),
-				},
-			},
-			PublishedAt: &Timestamp{referenceTime},
-			UpdatedAt:   &Timestamp{referenceTime},
-			WithdrawnAt: nil,
-			Vulnerabilities: []*AdvisoryVulnerability{
-				{
-					Package: &VulnerabilityPackage{
-						Ecosystem: String("ucl"),
-						Name:      String("penaldo"),
-					},
-					Severity:               String("moderate"),
-					VulnerableVersionRange: String(">= 2.0.0, < 2.0.2"),
-					FirstPatchedVersion: &FirstPatchedVersion{
-						Identifier: String("2.0.2"),
-					},
-				},
-			},
 		},
-	}
-
-	want := `{
-		"action": "published",
-		"security_advisory": {
-		  "ghsa_id": "GHSA-rf4j-j272-some",
-		  "summary": "Siuuuuuuuuu",
-		  "description": "desc",
-		  "severity": "moderate",
-		  "identifiers": [
-			{
-			  "value": "GHSA-rf4j-j272-some",
-			  "type": "GHSA"
-			}
-		  ],
-		  "references": [
-			{
-			  "url": "https://some-url"
-			}
-		  ],
-		  "published_at": ` + referenceTimeStr + `,
-		  "updated_at": ` + referenceTimeStr + `,
-		  "withdrawn_at": null,
-		  "vulnerabilities": [
-			{
-			  "package": {
-				"ecosystem": "ucl",
-				"name": "penaldo"
-			  },
-			  "severity": "moderate",
-			  "vulnerable_version_range": ">= 2.0.0, < 2.0.2",
-			  "first_patched_version": {
-				"identifier": "2.0.2"
-			  }
-			}
-		  ]
-		}
-	  }`
+		"organization": {
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "loc",
+			"email": "e",
+			"twitter_username": "tu",
+			"description": "d",
+			"billing_email": "be",
+			"is_verified": true,
+			"has_organization_projects": true,
+			"has_repository_projects": true,
+			"default_repository_permission": "drp",
+			"members_can_create_repositories": true,
+			"members_can_create_public_repositories": false,
+			"members_can_create_private_repositories": true,
+			"members_can_create_internal_repositories": true,
+			"members_allowed_repository_creation_type": "marct",
+			"members_can_create_pages": true,
+			"members_can_create_public_pages": false,
+			"members_can_create_private_pages": true
+		},
+		"repository": {
+			"id": 1,
+			"url": "s",
+			"name": "n"
+		},
+		"sender": {
+			"login": "l",
+			"id": 1,
+			"node_id": "n",
+			"avatar_url": "a",
+			"url": "u",
+			"events_url": "e",
+			"repos_url": "r"
+		},
+		"target_type": "running"
+	}`
 
 	testJSONMarshal(t, u, want)
 }
diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go
index 712d8fc9..12d05f2d 100644
--- a/github/github-accessors_test.go
+++ b/github/github-accessors_test.go
@@ -996,6 +996,26 @@ func TestAppConfig_GetWebhookSecret(tt *testing.T) {
 	a.GetWebhookSecret()
 }
 
+func TestArchivedAt_GetFrom(tt *testing.T) {
+	var zeroValue Timestamp
+	a := &ArchivedAt{From: &zeroValue}
+	a.GetFrom()
+	a = &ArchivedAt{}
+	a.GetFrom()
+	a = nil
+	a.GetFrom()
+}
+
+func TestArchivedAt_GetTo(tt *testing.T) {
+	var zeroValue Timestamp
+	a := &ArchivedAt{To: &zeroValue}
+	a.GetTo()
+	a = &ArchivedAt{}
+	a.GetTo()
+	a = nil
+	a.GetTo()
+}
+
 func TestArtifact_GetArchiveDownloadURL(tt *testing.T) {
 	var zeroValue string
 	a := &Artifact{ArchiveDownloadURL: &zeroValue}
@@ -16804,6 +16824,314 @@ func TestProjectPermissionLevel_GetUser(tt *testing.T) {
 	p.GetUser()
 }
 
+func TestProjectsV2_GetClosedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	p := &ProjectsV2{ClosedAt: &zeroValue}
+	p.GetClosedAt()
+	p = &ProjectsV2{}
+	p.GetClosedAt()
+	p = nil
+	p.GetClosedAt()
+}
+
+func TestProjectsV2_GetCreatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	p := &ProjectsV2{CreatedAt: &zeroValue}
+	p.GetCreatedAt()
+	p = &ProjectsV2{}
+	p.GetCreatedAt()
+	p = nil
+	p.GetCreatedAt()
+}
+
+func TestProjectsV2_GetCreator(tt *testing.T) {
+	p := &ProjectsV2{}
+	p.GetCreator()
+	p = nil
+	p.GetCreator()
+}
+
+func TestProjectsV2_GetDeletedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	p := &ProjectsV2{DeletedAt: &zeroValue}
+	p.GetDeletedAt()
+	p = &ProjectsV2{}
+	p.GetDeletedAt()
+	p = nil
+	p.GetDeletedAt()
+}
+
+func TestProjectsV2_GetDeletedBy(tt *testing.T) {
+	p := &ProjectsV2{}
+	p.GetDeletedBy()
+	p = nil
+	p.GetDeletedBy()
+}
+
+func TestProjectsV2_GetDescription(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectsV2{Description: &zeroValue}
+	p.GetDescription()
+	p = &ProjectsV2{}
+	p.GetDescription()
+	p = nil
+	p.GetDescription()
+}
+
+func TestProjectsV2_GetID(tt *testing.T) {
+	var zeroValue int64
+	p := &ProjectsV2{ID: &zeroValue}
+	p.GetID()
+	p = &ProjectsV2{}
+	p.GetID()
+	p = nil
+	p.GetID()
+}
+
+func TestProjectsV2_GetNodeID(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectsV2{NodeID: &zeroValue}
+	p.GetNodeID()
+	p = &ProjectsV2{}
+	p.GetNodeID()
+	p = nil
+	p.GetNodeID()
+}
+
+func TestProjectsV2_GetNumber(tt *testing.T) {
+	var zeroValue int
+	p := &ProjectsV2{Number: &zeroValue}
+	p.GetNumber()
+	p = &ProjectsV2{}
+	p.GetNumber()
+	p = nil
+	p.GetNumber()
+}
+
+func TestProjectsV2_GetOwner(tt *testing.T) {
+	p := &ProjectsV2{}
+	p.GetOwner()
+	p = nil
+	p.GetOwner()
+}
+
+func TestProjectsV2_GetPublic(tt *testing.T) {
+	var zeroValue bool
+	p := &ProjectsV2{Public: &zeroValue}
+	p.GetPublic()
+	p = &ProjectsV2{}
+	p.GetPublic()
+	p = nil
+	p.GetPublic()
+}
+
+func TestProjectsV2_GetShortDescription(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectsV2{ShortDescription: &zeroValue}
+	p.GetShortDescription()
+	p = &ProjectsV2{}
+	p.GetShortDescription()
+	p = nil
+	p.GetShortDescription()
+}
+
+func TestProjectsV2_GetTitle(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectsV2{Title: &zeroValue}
+	p.GetTitle()
+	p = &ProjectsV2{}
+	p.GetTitle()
+	p = nil
+	p.GetTitle()
+}
+
+func TestProjectsV2_GetUpdatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	p := &ProjectsV2{UpdatedAt: &zeroValue}
+	p.GetUpdatedAt()
+	p = &ProjectsV2{}
+	p.GetUpdatedAt()
+	p = nil
+	p.GetUpdatedAt()
+}
+
+func TestProjectV2Event_GetAction(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectV2Event{Action: &zeroValue}
+	p.GetAction()
+	p = &ProjectV2Event{}
+	p.GetAction()
+	p = nil
+	p.GetAction()
+}
+
+func TestProjectV2Event_GetInstallation(tt *testing.T) {
+	p := &ProjectV2Event{}
+	p.GetInstallation()
+	p = nil
+	p.GetInstallation()
+}
+
+func TestProjectV2Event_GetOrg(tt *testing.T) {
+	p := &ProjectV2Event{}
+	p.GetOrg()
+	p = nil
+	p.GetOrg()
+}
+
+func TestProjectV2Event_GetProjectsV2(tt *testing.T) {
+	p := &ProjectV2Event{}
+	p.GetProjectsV2()
+	p = nil
+	p.GetProjectsV2()
+}
+
+func TestProjectV2Event_GetSender(tt *testing.T) {
+	p := &ProjectV2Event{}
+	p.GetSender()
+	p = nil
+	p.GetSender()
+}
+
+func TestProjectV2Item_GetArchivedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	p := &ProjectV2Item{ArchivedAt: &zeroValue}
+	p.GetArchivedAt()
+	p = &ProjectV2Item{}
+	p.GetArchivedAt()
+	p = nil
+	p.GetArchivedAt()
+}
+
+func TestProjectV2Item_GetContentNodeID(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectV2Item{ContentNodeID: &zeroValue}
+	p.GetContentNodeID()
+	p = &ProjectV2Item{}
+	p.GetContentNodeID()
+	p = nil
+	p.GetContentNodeID()
+}
+
+func TestProjectV2Item_GetContentType(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectV2Item{ContentType: &zeroValue}
+	p.GetContentType()
+	p = &ProjectV2Item{}
+	p.GetContentType()
+	p = nil
+	p.GetContentType()
+}
+
+func TestProjectV2Item_GetCreatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	p := &ProjectV2Item{CreatedAt: &zeroValue}
+	p.GetCreatedAt()
+	p = &ProjectV2Item{}
+	p.GetCreatedAt()
+	p = nil
+	p.GetCreatedAt()
+}
+
+func TestProjectV2Item_GetCreator(tt *testing.T) {
+	p := &ProjectV2Item{}
+	p.GetCreator()
+	p = nil
+	p.GetCreator()
+}
+
+func TestProjectV2Item_GetID(tt *testing.T) {
+	var zeroValue int64
+	p := &ProjectV2Item{ID: &zeroValue}
+	p.GetID()
+	p = &ProjectV2Item{}
+	p.GetID()
+	p = nil
+	p.GetID()
+}
+
+func TestProjectV2Item_GetNodeID(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectV2Item{NodeID: &zeroValue}
+	p.GetNodeID()
+	p = &ProjectV2Item{}
+	p.GetNodeID()
+	p = nil
+	p.GetNodeID()
+}
+
+func TestProjectV2Item_GetProjectNodeID(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectV2Item{ProjectNodeID: &zeroValue}
+	p.GetProjectNodeID()
+	p = &ProjectV2Item{}
+	p.GetProjectNodeID()
+	p = nil
+	p.GetProjectNodeID()
+}
+
+func TestProjectV2Item_GetUpdatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	p := &ProjectV2Item{UpdatedAt: &zeroValue}
+	p.GetUpdatedAt()
+	p = &ProjectV2Item{}
+	p.GetUpdatedAt()
+	p = nil
+	p.GetUpdatedAt()
+}
+
+func TestProjectV2ItemChange_GetArchivedAt(tt *testing.T) {
+	p := &ProjectV2ItemChange{}
+	p.GetArchivedAt()
+	p = nil
+	p.GetArchivedAt()
+}
+
+func TestProjectV2ItemEvent_GetAction(tt *testing.T) {
+	var zeroValue string
+	p := &ProjectV2ItemEvent{Action: &zeroValue}
+	p.GetAction()
+	p = &ProjectV2ItemEvent{}
+	p.GetAction()
+	p = nil
+	p.GetAction()
+}
+
+func TestProjectV2ItemEvent_GetChanges(tt *testing.T) {
+	p := &ProjectV2ItemEvent{}
+	p.GetChanges()
+	p = nil
+	p.GetChanges()
+}
+
+func TestProjectV2ItemEvent_GetInstallation(tt *testing.T) {
+	p := &ProjectV2ItemEvent{}
+	p.GetInstallation()
+	p = nil
+	p.GetInstallation()
+}
+
+func TestProjectV2ItemEvent_GetOrg(tt *testing.T) {
+	p := &ProjectV2ItemEvent{}
+	p.GetOrg()
+	p = nil
+	p.GetOrg()
+}
+
+func TestProjectV2ItemEvent_GetProjectV2Item(tt *testing.T) {
+	p := &ProjectV2ItemEvent{}
+	p.GetProjectV2Item()
+	p = nil
+	p.GetProjectV2Item()
+}
+
+func TestProjectV2ItemEvent_GetSender(tt *testing.T) {
+	p := &ProjectV2ItemEvent{}
+	p.GetSender()
+	p = nil
+	p.GetSender()
+}
+
 func TestProtection_GetAllowDeletions(tt *testing.T) {
 	p := &Protection{}
 	p.GetAllowDeletions()
@@ -23643,6 +23971,62 @@ func TestSecurityAndAnalysis_GetSecretScanningPushProtection(tt *testing.T) {
 	s.GetSecretScanningPushProtection()
 }
 
+func TestSecurityAndAnalysisChange_GetFrom(tt *testing.T) {
+	s := &SecurityAndAnalysisChange{}
+	s.GetFrom()
+	s = nil
+	s.GetFrom()
+}
+
+func TestSecurityAndAnalysisChangeFrom_GetSecurityAndAnalysis(tt *testing.T) {
+	s := &SecurityAndAnalysisChangeFrom{}
+	s.GetSecurityAndAnalysis()
+	s = nil
+	s.GetSecurityAndAnalysis()
+}
+
+func TestSecurityAndAnalysisEvent_GetChanges(tt *testing.T) {
+	s := &SecurityAndAnalysisEvent{}
+	s.GetChanges()
+	s = nil
+	s.GetChanges()
+}
+
+func TestSecurityAndAnalysisEvent_GetEnterprise(tt *testing.T) {
+	s := &SecurityAndAnalysisEvent{}
+	s.GetEnterprise()
+	s = nil
+	s.GetEnterprise()
+}
+
+func TestSecurityAndAnalysisEvent_GetInstallation(tt *testing.T) {
+	s := &SecurityAndAnalysisEvent{}
+	s.GetInstallation()
+	s = nil
+	s.GetInstallation()
+}
+
+func TestSecurityAndAnalysisEvent_GetOrganization(tt *testing.T) {
+	s := &SecurityAndAnalysisEvent{}
+	s.GetOrganization()
+	s = nil
+	s.GetOrganization()
+}
+
+func TestSecurityAndAnalysisEvent_GetRepository(tt *testing.T) {
+	s := &SecurityAndAnalysisEvent{}
+	s.GetRepository()
+	s = nil
+	s.GetRepository()
+}
+
+func TestSecurityAndAnalysisEvent_GetSender(tt *testing.T) {
+	s := &SecurityAndAnalysisEvent{}
+	s.GetSender()
+	s = nil
+	s.GetSender()
+}
+
 func TestSelectedReposList_GetTotalCount(tt *testing.T) {
 	var zeroValue int
 	s := &SelectedReposList{TotalCount: &zeroValue}
diff --git a/github/messages_test.go b/github/messages_test.go
index 8ee38eb3..91a25027 100644
--- a/github/messages_test.go
+++ b/github/messages_test.go
@@ -404,6 +404,14 @@ func TestParseWebHook(t *testing.T) {
 			payload:     &ProjectColumnEvent{},
 			messageType: "project_column",
 		},
+		{
+			payload:     &ProjectV2Event{},
+			messageType: "projects_v2",
+		},
+		{
+			payload:     &ProjectV2ItemEvent{},
+			messageType: "projects_v2_item",
+		},
 		{
 			payload:     &PublicEvent{},
 			messageType: "public",
@@ -452,6 +460,10 @@ func TestParseWebHook(t *testing.T) {
 			payload:     &SecurityAdvisoryEvent{},
 			messageType: "security_advisory",
 		},
+		{
+			payload:     &SecurityAndAnalysisEvent{},
+			messageType: "security_and_analysis",
+		},
 		{
 			payload:     &StarEvent{},
 			messageType: "star",
diff --git a/github/repos_hooks_deliveries_test.go b/github/repos_hooks_deliveries_test.go
index d1dda365..d5e1a383 100644
--- a/github/repos_hooks_deliveries_test.go
+++ b/github/repos_hooks_deliveries_test.go
@@ -176,6 +176,8 @@ var hookDeliveryPayloadTypeToStruct = map[string]interface{}{
 	"project":                        &ProjectEvent{},
 	"project_card":                   &ProjectCardEvent{},
 	"project_column":                 &ProjectColumnEvent{},
+	"projects_v2":                    &ProjectV2Event{},
+	"projects_v2_item":               &ProjectV2ItemEvent{},
 	"public":                         &PublicEvent{},
 	"pull_request":                   &PullRequestEvent{},
 	"pull_request_review":            &PullRequestReviewEvent{},
@@ -190,6 +192,7 @@ var hookDeliveryPayloadTypeToStruct = map[string]interface{}{
 	"repository_vulnerability_alert": &RepositoryVulnerabilityAlertEvent{},
 	"secret_scanning_alert":          &SecretScanningAlertEvent{},
 	"security_advisory":              &SecurityAdvisoryEvent{},
+	"security_and_analysis":          &SecurityAndAnalysisEvent{},
 	"star":                           &StarEvent{},
 	"status":                         &StatusEvent{},
 	"team":                           &TeamEvent{},