Skip to content

Commit

Permalink
Restrict [actions].DEFAULT_ACTIONS_URL to only github or self (g…
Browse files Browse the repository at this point in the history
…o-gitea#25581) (go-gitea#25604)

Backport go-gitea#25581 by @wolfogre

Resolve go-gitea#24789

## ⚠️ BREAKING ⚠️

Before this, `DEFAULT_ACTIONS_URL` cound be set to any custom URLs like
`https://gitea.com` or `http://your-git-server,https://gitea.com`, and
the default value was `https://gitea.com`.

But now, `DEFAULT_ACTIONS_URL` supports only
`github`(`https://github.com`) or `self`(the root url of current Gitea
instance), and the default value is `github`.

If it has configured with a URL, an error log will be displayed and it
will fallback to `github`.

Actually, what we really want to do is always make it
`https://github.com`, however, this may not be acceptable for some
instances of internal use, so there's extra support for `self`, but no
more, even `https://gitea.com`.

Please note that `uses: https://xxx/yyy/zzz` always works and it does
exactly what it is supposed to do.

Although it's breaking, I belive it should be backported to `v1.20` due
to some security issues.

Follow-up on the runner side:

- https://gitea.com/gitea/act_runner/pulls/262
- https://gitea.com/gitea/act/pulls/70

Co-authored-by: Jason Song <i@wolfogre.com>
  • Loading branch information
GiteaBot and wolfogre authored Jun 30, 2023
1 parent 0b6f7fb commit 24cf065
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 33 deletions.
4 changes: 2 additions & 2 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2541,8 +2541,8 @@ LEVEL = Info
;; Enable/Disable actions capabilities
;ENABLED = false
;;
;; Default address to get action plugins, e.g. the default value means downloading from "https://gitea.com/actions/checkout" for "uses: actions/checkout@v3"
;DEFAULT_ACTIONS_URL = https://gitea.com
;; Default platform to get action plugins, `github` for `https://github.com`, `self` for the current Gitea instance.
;DEFAULT_ACTIONS_URL = github

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
39 changes: 11 additions & 28 deletions docs/content/doc/administration/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -1374,39 +1374,22 @@ PROXY_HOSTS = *.git.luolix.top
## Actions (`actions`)

- `ENABLED`: **false**: Enable/Disable actions capabilities
- `DEFAULT_ACTIONS_URL`: **https://gitea.com**: Default address to get action plugins, e.g. the default value means downloading from "<https://gitea.com/actions/checkout>" for "uses: actions/checkout@v3"
- `DEFAULT_ACTIONS_URL`: **github**: Default platform to get action plugins, `github` for `https://github.com`, `self` for the current Gitea instance.
- `STORAGE_TYPE`: **local**: Storage type for actions logs, `local` for local disk or `minio` for s3 compatible object storage service, default is `local` or other name defined with `[storage.xxx]`
- `MINIO_BASE_PATH`: **actions_log/**: Minio base path on the bucket only available when STORAGE_TYPE is `minio`

`DEFAULT_ACTIONS_URL` indicates where should we find the relative path action plugin. i.e. when use an action in a workflow file like

```yaml
name: versions
on:
push:
branches:
- main
- releases/*
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
```
Now we need to know how to get actions/checkout, this configuration is the default git server to get it. That means we will get the repository via git clone ${DEFAULT_ACTIONS_URL}/actions/checkout and fetch tag v3.
To help people who don't want to mirror these actions in their git instances, the default value is https://gitea.com
To help people run actions totally in their network, they can change the value and copy all necessary action repositories into their git server.
`DEFAULT_ACTIONS_URL` indicates where the Gitea Actions runners should find the actions with relative path.
For example, `uses: actions/checkout@v3` means `https://github.com/actions/checkout@v3` since the value of `DEFAULT_ACTIONS_URL` is `github`.
And it can be changed to `self` to make it `root_url_of_your_gitea/actions/checkout@v3`.

Of course we should support the form in future PRs like
```yaml
steps:
- uses: gitea.com/actions/checkout@v3
```
Please note that using `self` is not recommended for most cases, as it could make names globally ambiguous.
Additionally, it requires you to mirror all the actions you need to your Gitea instance, which may not be worth it.
Therefore, please use `self` only if you understand what you are doing.

although Github don't support this form.
In earlier versions (<= 1.19), `DEFAULT_ACTIONS_URL` cound be set to any custom URLs like `https://gitea.com` or `http://your-git-server,https://gitea.com`, and the default value was `https://gitea.com`.
However, later updates removed those options, and now the only options are `github` and `self`, with the default value being `github`.
However, if you want to use actions from other git server, you can use a complete URL in `uses` field, it's supported by Gitea (but not GitHub).
Like `uses: https://gitea.com/actions/checkout@v3` or `uses: http://your-git-server/actions/checkout@v3`.

## Other (`other`)

Expand Down
43 changes: 41 additions & 2 deletions modules/setting/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ package setting

import (
"fmt"
"strings"

"code.gitea.io/gitea/modules/log"
)

// Actions settings
Expand All @@ -13,20 +16,56 @@ var (
LogStorage *Storage // how the created logs should be stored
ArtifactStorage *Storage // how the created artifacts should be stored
Enabled bool
DefaultActionsURL string `ini:"DEFAULT_ACTIONS_URL"`
DefaultActionsURL defaultActionsURL `ini:"DEFAULT_ACTIONS_URL"`
}{
Enabled: false,
DefaultActionsURL: "https://gitea.com",
DefaultActionsURL: defaultActionsURLGitHub,
}
)

type defaultActionsURL string

func (url defaultActionsURL) URL() string {
switch url {
case defaultActionsURLGitHub:
return "https://github.com"
case defaultActionsURLSelf:
return strings.TrimSuffix(AppURL, "/")
default:
// This should never happen, but just in case, use GitHub as fallback
return "https://github.com"
}
}

const (
defaultActionsURLGitHub = "github" // https://github.com
defaultActionsURLSelf = "self" // the root URL of the self-hosted Gitea instance
// DefaultActionsURL only supports GitHub and the self-hosted Gitea.
// It's intentionally not supported more, so please be cautious before adding more like "gitea" or "gitlab".
// If you get some trouble with `uses: username/action_name@version` in your workflow,
// please consider to use `uses: https://the_url_you_want_to_use/username/action_name@version` instead.
)

func loadActionsFrom(rootCfg ConfigProvider) error {
sec := rootCfg.Section("actions")
err := sec.MapTo(&Actions)
if err != nil {
return fmt.Errorf("failed to map Actions settings: %v", err)
}

if urls := string(Actions.DefaultActionsURL); urls != defaultActionsURLGitHub && urls != defaultActionsURLSelf {
url := strings.Split(urls, ",")[0]
if strings.HasPrefix(url, "https://") || strings.HasPrefix(url, "http://") {
log.Error("[actions] DEFAULT_ACTIONS_URL does not support %q as custom URL any longer, fallback to %q",
urls,
defaultActionsURLGitHub,
)
Actions.DefaultActionsURL = defaultActionsURLGitHub
} else {
return fmt.Errorf("unsupported [actions] DEFAULT_ACTIONS_URL: %q", urls)
}
}

// don't support to read configuration from [actions]
Actions.LogStorage, err = getStorage(rootCfg, "actions_log", "", nil)
if err != nil {
Expand Down
84 changes: 84 additions & 0 deletions modules/setting/actions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Test_getStorageInheritNameSectionTypeForActions(t *testing.T) {
Expand Down Expand Up @@ -95,3 +96,86 @@ STORAGE_TYPE = minio
assert.EqualValues(t, "local", Actions.ArtifactStorage.Type)
assert.EqualValues(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path))
}

func Test_getDefaultActionsURLForActions(t *testing.T) {
oldActions := Actions
oldAppURL := AppURL
defer func() {
Actions = oldActions
AppURL = oldAppURL
}()

AppURL = "http://test_get_default_actions_url_for_actions:3000/"

tests := []struct {
name string
iniStr string
wantErr assert.ErrorAssertionFunc
wantURL string
}{
{
name: "default",
iniStr: `
[actions]
`,
wantErr: assert.NoError,
wantURL: "https://github.com",
},
{
name: "github",
iniStr: `
[actions]
DEFAULT_ACTIONS_URL = github
`,
wantErr: assert.NoError,
wantURL: "https://github.com",
},
{
name: "self",
iniStr: `
[actions]
DEFAULT_ACTIONS_URL = self
`,
wantErr: assert.NoError,
wantURL: "http://test_get_default_actions_url_for_actions:3000",
},
{
name: "custom url",
iniStr: `
[actions]
DEFAULT_ACTIONS_URL = https://gitea.com
`,
wantErr: assert.NoError,
wantURL: "https://github.com",
},
{
name: "custom urls",
iniStr: `
[actions]
DEFAULT_ACTIONS_URL = https://gitea.com,https://github.com
`,
wantErr: assert.NoError,
wantURL: "https://github.com",
},
{
name: "invalid",
iniStr: `
[actions]
DEFAULT_ACTIONS_URL = gitea
`,
wantErr: assert.Error,
wantURL: "https://github.com",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg, err := NewConfigProviderFromData(tt.iniStr)
require.NoError(t, err)
if !tt.wantErr(t, loadActionsFrom(cfg)) {
return
}
assert.EqualValues(t, tt.wantURL, Actions.DefaultActionsURL.URL())
})
}
}
2 changes: 1 addition & 1 deletion routers/api/actions/runner/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct {
"workspace": "", // string, The default working directory on the runner for steps, and the default location of your repository when using the checkout action.

// additional contexts
"gitea_default_actions_url": setting.Actions.DefaultActionsURL,
"gitea_default_actions_url": setting.Actions.DefaultActionsURL.URL(),
})
if err != nil {
log.Error("structpb.NewStruct failed: %v", err)
Expand Down

0 comments on commit 24cf065

Please sign in to comment.