code.gitea.io/gitea@v1.21.7/services/repository/hooks.go (about)

     1  // Copyright 2021 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package repository
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"code.gitea.io/gitea/models/db"
    11  	repo_model "code.gitea.io/gitea/models/repo"
    12  	"code.gitea.io/gitea/models/webhook"
    13  	"code.gitea.io/gitea/modules/git"
    14  	"code.gitea.io/gitea/modules/log"
    15  	repo_module "code.gitea.io/gitea/modules/repository"
    16  
    17  	"xorm.io/builder"
    18  )
    19  
    20  // SyncRepositoryHooks rewrites all repositories' pre-receive, update and post-receive hooks
    21  // to make sure the binary and custom conf path are up-to-date.
    22  func SyncRepositoryHooks(ctx context.Context) error {
    23  	log.Trace("Doing: SyncRepositoryHooks")
    24  
    25  	if err := db.Iterate(
    26  		ctx,
    27  		builder.Gt{"id": 0},
    28  		func(ctx context.Context, repo *repo_model.Repository) error {
    29  			select {
    30  			case <-ctx.Done():
    31  				return db.ErrCancelledf("before sync repository hooks for %s", repo.FullName())
    32  			default:
    33  			}
    34  
    35  			if err := repo_module.CreateDelegateHooks(repo.RepoPath()); err != nil {
    36  				return fmt.Errorf("SyncRepositoryHook: %w", err)
    37  			}
    38  			if repo.HasWiki() {
    39  				if err := repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil {
    40  					return fmt.Errorf("SyncRepositoryHook: %w", err)
    41  				}
    42  			}
    43  			return nil
    44  		},
    45  	); err != nil {
    46  		return err
    47  	}
    48  
    49  	log.Trace("Finished: SyncRepositoryHooks")
    50  	return nil
    51  }
    52  
    53  // GenerateGitHooks generates git hooks from a template repository
    54  func GenerateGitHooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
    55  	generateGitRepo, err := git.OpenRepository(ctx, generateRepo.RepoPath())
    56  	if err != nil {
    57  		return err
    58  	}
    59  	defer generateGitRepo.Close()
    60  
    61  	templateGitRepo, err := git.OpenRepository(ctx, templateRepo.RepoPath())
    62  	if err != nil {
    63  		return err
    64  	}
    65  	defer templateGitRepo.Close()
    66  
    67  	templateHooks, err := templateGitRepo.Hooks()
    68  	if err != nil {
    69  		return err
    70  	}
    71  
    72  	for _, templateHook := range templateHooks {
    73  		generateHook, err := generateGitRepo.GetHook(templateHook.Name())
    74  		if err != nil {
    75  			return err
    76  		}
    77  
    78  		generateHook.Content = templateHook.Content
    79  		if err := generateHook.Update(); err != nil {
    80  			return err
    81  		}
    82  	}
    83  	return nil
    84  }
    85  
    86  // GenerateWebhooks generates webhooks from a template repository
    87  func GenerateWebhooks(ctx context.Context, templateRepo, generateRepo *repo_model.Repository) error {
    88  	templateWebhooks, err := webhook.ListWebhooksByOpts(ctx, &webhook.ListWebhookOptions{RepoID: templateRepo.ID})
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	ws := make([]*webhook.Webhook, 0, len(templateWebhooks))
    94  	for _, templateWebhook := range templateWebhooks {
    95  		ws = append(ws, &webhook.Webhook{
    96  			RepoID:      generateRepo.ID,
    97  			URL:         templateWebhook.URL,
    98  			HTTPMethod:  templateWebhook.HTTPMethod,
    99  			ContentType: templateWebhook.ContentType,
   100  			Secret:      templateWebhook.Secret,
   101  			HookEvent:   templateWebhook.HookEvent,
   102  			IsActive:    templateWebhook.IsActive,
   103  			Type:        templateWebhook.Type,
   104  			OwnerID:     templateWebhook.OwnerID,
   105  			Events:      templateWebhook.Events,
   106  			Meta:        templateWebhook.Meta,
   107  		})
   108  	}
   109  	return webhook.CreateWebhooks(ctx, ws)
   110  }