...

Source file src/github.com/google/go-github/v55/github/migrations.go

Documentation: github.com/google/go-github/v55/github

     1  // Copyright 2016 The go-github AUTHORS. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package github
     7  
     8  import (
     9  	"context"
    10  	"errors"
    11  	"fmt"
    12  	"net/http"
    13  	"strings"
    14  )
    15  
    16  // MigrationService provides access to the migration related functions
    17  // in the GitHub API.
    18  //
    19  // GitHub API docs: https://docs.github.com/en/rest/migration/
    20  type MigrationService service
    21  
    22  // Migration represents a GitHub migration (archival).
    23  type Migration struct {
    24  	ID   *int64  `json:"id,omitempty"`
    25  	GUID *string `json:"guid,omitempty"`
    26  	// State is the current state of a migration.
    27  	// Possible values are:
    28  	//     "pending" which means the migration hasn't started yet,
    29  	//     "exporting" which means the migration is in progress,
    30  	//     "exported" which means the migration finished successfully, or
    31  	//     "failed" which means the migration failed.
    32  	State *string `json:"state,omitempty"`
    33  	// LockRepositories indicates whether repositories are locked (to prevent
    34  	// manipulation) while migrating data.
    35  	LockRepositories *bool `json:"lock_repositories,omitempty"`
    36  	// ExcludeAttachments indicates whether attachments should be excluded from
    37  	// the migration (to reduce migration archive file size).
    38  	ExcludeAttachments *bool         `json:"exclude_attachments,omitempty"`
    39  	URL                *string       `json:"url,omitempty"`
    40  	CreatedAt          *string       `json:"created_at,omitempty"`
    41  	UpdatedAt          *string       `json:"updated_at,omitempty"`
    42  	Repositories       []*Repository `json:"repositories,omitempty"`
    43  }
    44  
    45  func (m Migration) String() string {
    46  	return Stringify(m)
    47  }
    48  
    49  // MigrationOptions specifies the optional parameters to Migration methods.
    50  type MigrationOptions struct {
    51  	// LockRepositories indicates whether repositories should be locked (to prevent
    52  	// manipulation) while migrating data.
    53  	LockRepositories bool
    54  
    55  	// ExcludeAttachments indicates whether attachments should be excluded from
    56  	// the migration (to reduce migration archive file size).
    57  	ExcludeAttachments bool
    58  }
    59  
    60  // startMigration represents the body of a StartMigration request.
    61  type startMigration struct {
    62  	// Repositories is a slice of repository names to migrate.
    63  	Repositories []string `json:"repositories,omitempty"`
    64  
    65  	// LockRepositories indicates whether repositories should be locked (to prevent
    66  	// manipulation) while migrating data.
    67  	LockRepositories *bool `json:"lock_repositories,omitempty"`
    68  
    69  	// ExcludeAttachments indicates whether attachments should be excluded from
    70  	// the migration (to reduce migration archive file size).
    71  	ExcludeAttachments *bool `json:"exclude_attachments,omitempty"`
    72  }
    73  
    74  // StartMigration starts the generation of a migration archive.
    75  // repos is a slice of repository names to migrate.
    76  //
    77  // GitHub API docs: https://docs.github.com/en/rest/migrations/orgs#start-an-organization-migration
    78  func (s *MigrationService) StartMigration(ctx context.Context, org string, repos []string, opts *MigrationOptions) (*Migration, *Response, error) {
    79  	u := fmt.Sprintf("orgs/%v/migrations", org)
    80  
    81  	body := &startMigration{Repositories: repos}
    82  	if opts != nil {
    83  		body.LockRepositories = Bool(opts.LockRepositories)
    84  		body.ExcludeAttachments = Bool(opts.ExcludeAttachments)
    85  	}
    86  
    87  	req, err := s.client.NewRequest("POST", u, body)
    88  	if err != nil {
    89  		return nil, nil, err
    90  	}
    91  
    92  	// TODO: remove custom Accept header when this API fully launches.
    93  	req.Header.Set("Accept", mediaTypeMigrationsPreview)
    94  
    95  	m := &Migration{}
    96  	resp, err := s.client.Do(ctx, req, m)
    97  	if err != nil {
    98  		return nil, resp, err
    99  	}
   100  
   101  	return m, resp, nil
   102  }
   103  
   104  // ListMigrations lists the most recent migrations.
   105  //
   106  // GitHub API docs: https://docs.github.com/en/rest/migrations/orgs#list-organization-migrations
   107  func (s *MigrationService) ListMigrations(ctx context.Context, org string, opts *ListOptions) ([]*Migration, *Response, error) {
   108  	u := fmt.Sprintf("orgs/%v/migrations", org)
   109  	u, err := addOptions(u, opts)
   110  	if err != nil {
   111  		return nil, nil, err
   112  	}
   113  
   114  	req, err := s.client.NewRequest("GET", u, nil)
   115  	if err != nil {
   116  		return nil, nil, err
   117  	}
   118  
   119  	// TODO: remove custom Accept header when this API fully launches.
   120  	req.Header.Set("Accept", mediaTypeMigrationsPreview)
   121  
   122  	var m []*Migration
   123  	resp, err := s.client.Do(ctx, req, &m)
   124  	if err != nil {
   125  		return nil, resp, err
   126  	}
   127  
   128  	return m, resp, nil
   129  }
   130  
   131  // MigrationStatus gets the status of a specific migration archive.
   132  // id is the migration ID.
   133  //
   134  // GitHub API docs: https://docs.github.com/en/rest/migrations/orgs#get-an-organization-migration-status
   135  func (s *MigrationService) MigrationStatus(ctx context.Context, org string, id int64) (*Migration, *Response, error) {
   136  	u := fmt.Sprintf("orgs/%v/migrations/%v", org, id)
   137  
   138  	req, err := s.client.NewRequest("GET", u, nil)
   139  	if err != nil {
   140  		return nil, nil, err
   141  	}
   142  
   143  	// TODO: remove custom Accept header when this API fully launches.
   144  	req.Header.Set("Accept", mediaTypeMigrationsPreview)
   145  
   146  	m := &Migration{}
   147  	resp, err := s.client.Do(ctx, req, m)
   148  	if err != nil {
   149  		return nil, resp, err
   150  	}
   151  
   152  	return m, resp, nil
   153  }
   154  
   155  // MigrationArchiveURL fetches a migration archive URL.
   156  // id is the migration ID.
   157  //
   158  // GitHub API docs: https://docs.github.com/en/rest/migrations/orgs#download-an-organization-migration-archive
   159  func (s *MigrationService) MigrationArchiveURL(ctx context.Context, org string, id int64) (url string, err error) {
   160  	u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id)
   161  
   162  	req, err := s.client.NewRequest("GET", u, nil)
   163  	if err != nil {
   164  		return "", err
   165  	}
   166  
   167  	// TODO: remove custom Accept header when this API fully launches.
   168  	req.Header.Set("Accept", mediaTypeMigrationsPreview)
   169  
   170  	s.client.clientMu.Lock()
   171  	defer s.client.clientMu.Unlock()
   172  
   173  	// Disable the redirect mechanism because AWS fails if the GitHub auth token is provided.
   174  	var loc string
   175  	saveRedirect := s.client.client.CheckRedirect
   176  	s.client.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
   177  		loc = req.URL.String()
   178  		return errors.New("disable redirect")
   179  	}
   180  	defer func() { s.client.client.CheckRedirect = saveRedirect }()
   181  
   182  	_, err = s.client.Do(ctx, req, nil) // expect error from disable redirect
   183  	if err == nil {
   184  		return "", errors.New("expected redirect, none provided")
   185  	}
   186  	if !strings.Contains(err.Error(), "disable redirect") {
   187  		return "", err
   188  	}
   189  	return loc, nil
   190  }
   191  
   192  // DeleteMigration deletes a previous migration archive.
   193  // id is the migration ID.
   194  //
   195  // GitHub API docs: https://docs.github.com/en/rest/migrations/orgs#delete-an-organization-migration-archive
   196  func (s *MigrationService) DeleteMigration(ctx context.Context, org string, id int64) (*Response, error) {
   197  	u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id)
   198  
   199  	req, err := s.client.NewRequest("DELETE", u, nil)
   200  	if err != nil {
   201  		return nil, err
   202  	}
   203  
   204  	// TODO: remove custom Accept header when this API fully launches.
   205  	req.Header.Set("Accept", mediaTypeMigrationsPreview)
   206  
   207  	return s.client.Do(ctx, req, nil)
   208  }
   209  
   210  // UnlockRepo unlocks a repository that was locked for migration.
   211  // id is the migration ID.
   212  // You should unlock each migrated repository and delete them when the migration
   213  // is complete and you no longer need the source data.
   214  //
   215  // GitHub API docs: https://docs.github.com/en/rest/migrations/orgs#unlock-an-organization-repository
   216  func (s *MigrationService) UnlockRepo(ctx context.Context, org string, id int64, repo string) (*Response, error) {
   217  	u := fmt.Sprintf("orgs/%v/migrations/%v/repos/%v/lock", org, id, repo)
   218  
   219  	req, err := s.client.NewRequest("DELETE", u, nil)
   220  	if err != nil {
   221  		return nil, err
   222  	}
   223  
   224  	// TODO: remove custom Accept header when this API fully launches.
   225  	req.Header.Set("Accept", mediaTypeMigrationsPreview)
   226  
   227  	return s.client.Do(ctx, req, nil)
   228  }
   229  

View as plain text