feat: support offline mode (#2128)

* Add: Actions Offline Mode

* Add: Actions Offline Mode

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
TKaxv_7S 2024-01-20 08:20:15 +08:00 committed by GitHub
parent f7a846d2f5
commit f055d4ae60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 31 additions and 19 deletions

View file

@ -55,6 +55,7 @@ type Input struct {
replaceGheActionTokenWithGithubCom string replaceGheActionTokenWithGithubCom string
matrix []string matrix []string
actionCachePath string actionCachePath string
actionOfflineMode bool
logPrefixJobID bool logPrefixJobID bool
networkName string networkName string
useNewActionCache bool useNewActionCache bool

View file

@ -97,6 +97,7 @@ func Execute(ctx context.Context, version string) {
rootCmd.PersistentFlags().StringVarP(&input.cacheServerAddr, "cache-server-addr", "", common.GetOutboundIP().String(), "Defines the address to which the cache server binds.") rootCmd.PersistentFlags().StringVarP(&input.cacheServerAddr, "cache-server-addr", "", common.GetOutboundIP().String(), "Defines the address to which the cache server binds.")
rootCmd.PersistentFlags().Uint16VarP(&input.cacheServerPort, "cache-server-port", "", 0, "Defines the port where the artifact server listens. 0 means a randomly available port.") rootCmd.PersistentFlags().Uint16VarP(&input.cacheServerPort, "cache-server-port", "", 0, "Defines the port where the artifact server listens. 0 means a randomly available port.")
rootCmd.PersistentFlags().StringVarP(&input.actionCachePath, "action-cache-path", "", filepath.Join(CacheHomeDir, "act"), "Defines the path where the actions get cached and host workspaces created.") rootCmd.PersistentFlags().StringVarP(&input.actionCachePath, "action-cache-path", "", filepath.Join(CacheHomeDir, "act"), "Defines the path where the actions get cached and host workspaces created.")
rootCmd.PersistentFlags().BoolVarP(&input.actionOfflineMode, "action-offline-mode", "", false, "If action contents exists, it will not be fetch and pull again. If turn on this,will turn off force pull")
rootCmd.PersistentFlags().StringVarP(&input.networkName, "network", "", "host", "Sets a docker network name. Defaults to host.") rootCmd.PersistentFlags().StringVarP(&input.networkName, "network", "", "host", "Sets a docker network name. Defaults to host.")
rootCmd.PersistentFlags().BoolVarP(&input.useNewActionCache, "use-new-action-cache", "", false, "Enable using the new Action Cache for storing Actions locally") rootCmd.PersistentFlags().BoolVarP(&input.useNewActionCache, "use-new-action-cache", "", false, "Enable using the new Action Cache for storing Actions locally")
rootCmd.SetArgs(args()) rootCmd.SetArgs(args())
@ -582,11 +583,12 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
EventName: eventName, EventName: eventName,
EventPath: input.EventPath(), EventPath: input.EventPath(),
DefaultBranch: defaultbranch, DefaultBranch: defaultbranch,
ForcePull: input.forcePull, ForcePull: !input.actionOfflineMode && input.forcePull,
ForceRebuild: input.forceRebuild, ForceRebuild: input.forceRebuild,
ReuseContainers: input.reuseContainers, ReuseContainers: input.reuseContainers,
Workdir: input.Workdir(), Workdir: input.Workdir(),
ActionCacheDir: input.actionCachePath, ActionCacheDir: input.actionCachePath,
ActionOfflineMode: input.actionOfflineMode,
BindWorkdir: input.bindWorkdir, BindWorkdir: input.bindWorkdir,
LogOutput: !input.noOutput, LogOutput: !input.noOutput,
JSONLogger: input.jsonLogger, JSONLogger: input.jsonLogger,

View file

@ -221,10 +221,11 @@ func findGitSlug(url string, githubInstance string) (string, string, error) {
// NewGitCloneExecutorInput the input for the NewGitCloneExecutor // NewGitCloneExecutorInput the input for the NewGitCloneExecutor
type NewGitCloneExecutorInput struct { type NewGitCloneExecutorInput struct {
URL string URL string
Ref string Ref string
Dir string Dir string
Token string Token string
OfflineMode bool
} }
// CloneIfRequired ... // CloneIfRequired ...
@ -302,12 +303,16 @@ func NewGitCloneExecutor(input NewGitCloneExecutorInput) common.Executor {
return err return err
} }
isOfflineMode := input.OfflineMode
// fetch latest changes // fetch latest changes
fetchOptions, pullOptions := gitOptions(input.Token) fetchOptions, pullOptions := gitOptions(input.Token)
err = r.Fetch(&fetchOptions) if !isOfflineMode {
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) { err = r.Fetch(&fetchOptions)
return err if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
return err
}
} }
var hash *plumbing.Hash var hash *plumbing.Hash
@ -367,9 +372,10 @@ func NewGitCloneExecutor(input NewGitCloneExecutorInput) common.Executor {
return err return err
} }
} }
if !isOfflineMode {
if err = w.Pull(&pullOptions); err != nil && err != git.NoErrAlreadyUpToDate { if err = w.Pull(&pullOptions); err != nil && err != git.NoErrAlreadyUpToDate {
logger.Debugf("Unable to pull %s: %v", refName, err) logger.Debugf("Unable to pull %s: %v", refName, err)
}
} }
logger.Debugf("Cloned %s to %s", input.URL, input.Dir) logger.Debugf("Cloned %s to %s", input.URL, input.Dir)

View file

@ -102,10 +102,11 @@ func cloneIfRequired(rc *RunContext, remoteReusableWorkflow remoteReusableWorkfl
func(ctx context.Context) error { func(ctx context.Context) error {
remoteReusableWorkflow.URL = rc.getGithubContext(ctx).ServerURL remoteReusableWorkflow.URL = rc.getGithubContext(ctx).ServerURL
return git.NewGitCloneExecutor(git.NewGitCloneExecutorInput{ return git.NewGitCloneExecutor(git.NewGitCloneExecutorInput{
URL: remoteReusableWorkflow.CloneURL(), URL: remoteReusableWorkflow.CloneURL(),
Ref: remoteReusableWorkflow.Ref, Ref: remoteReusableWorkflow.Ref,
Dir: targetDirectory, Dir: targetDirectory,
Token: rc.Config.Token, Token: rc.Config.Token,
OfflineMode: rc.Config.ActionOfflineMode,
})(ctx) })(ctx)
}, },
nil, nil,

View file

@ -23,6 +23,7 @@ type Config struct {
Actor string // the user that triggered the event Actor string // the user that triggered the event
Workdir string // path to working directory Workdir string // path to working directory
ActionCacheDir string // path used for caching action contents ActionCacheDir string // path used for caching action contents
ActionOfflineMode bool // when offline, use caching action contents
BindWorkdir bool // bind the workdir to the job container BindWorkdir bool // bind the workdir to the job container
EventName string // name of event to run EventName string // name of event to run
EventPath string // path to JSON file to use for event.json in containers EventPath string // path to JSON file to use for event.json in containers

View file

@ -106,10 +106,11 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses)) actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses))
gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{ gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{
URL: sar.remoteAction.CloneURL(), URL: sar.remoteAction.CloneURL(),
Ref: sar.remoteAction.Ref, Ref: sar.remoteAction.Ref,
Dir: actionDir, Dir: actionDir,
Token: github.Token, Token: github.Token,
OfflineMode: sar.RunContext.Config.ActionOfflineMode,
}) })
var ntErr common.Executor var ntErr common.Executor
if err := gitClone(ctx); err != nil { if err := gitClone(ctx); err != nil {