registry-add-entry
This change adds a registry-add-entry action. Signed-off-by: Ben Hale <bhale@vmware.com>
This commit is contained in:
parent
f9e5484fd3
commit
b3d523fb36
|
|
@ -3,11 +3,14 @@ name: Action buildpack-compute-metadata
|
|||
pull_request:
|
||||
paths:
|
||||
- buildpack/compute-metadata/**
|
||||
- internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- buildpack/compute-metadata/**
|
||||
- internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
|
|
|||
|
|
@ -3,11 +3,14 @@ name: Action buildpackage-verify-metadata
|
|||
pull_request:
|
||||
paths:
|
||||
- buildpackage/verify-metadata/**
|
||||
- internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- buildpackage/verify-metadata/**
|
||||
- internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
name: Action registry-add-entry
|
||||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/add-entry/**
|
||||
- registry/internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- internal/**
|
||||
- registry/add-entry/**
|
||||
- registry/internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
create-action:
|
||||
name: Create Action
|
||||
runs-on:
|
||||
- ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event_name != 'pull_request' || ! github.event.pull_request.head.repo.fork }}
|
||||
name: Docker login ghcr.io
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
password: ${{ secrets.IMPLEMENTATION_GITHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ secrets.IMPLEMENTATION_GITHUB_USERNAME }}
|
||||
- uses: actions/checkout@v2
|
||||
- id: version
|
||||
name: Compute Version
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ${GITHUB_REF} =~ refs/tags/v([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
elif [[ ${GITHUB_REF} =~ refs/heads/(.+) ]]; then
|
||||
VERSION=${BASH_REMATCH[1]}
|
||||
else
|
||||
VERSION=$(git rev-parse --short HEAD)
|
||||
fi
|
||||
|
||||
echo "::set-output name=version::${VERSION}"
|
||||
echo "Selected ${VERSION} from
|
||||
* ref: ${GITHUB_REF}
|
||||
* sha: ${GITHUB_SHA}
|
||||
"
|
||||
- name: Create Action
|
||||
run: |
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "::group::Building ${TARGET}:${VERSION}"
|
||||
docker build \
|
||||
--file Dockerfile \
|
||||
--build-arg "SOURCE=${SOURCE}" \
|
||||
--tag "${TARGET}:${VERSION}" \
|
||||
.
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ "${PUSH}" == "true" ]]; then
|
||||
echo "::group::Pushing ${TARGET}:${VERSION}"
|
||||
docker push "${TARGET}:${VERSION}"
|
||||
echo "::endgroup::"
|
||||
else
|
||||
echo "Skipping push"
|
||||
fi
|
||||
env:
|
||||
PUSH: ${{ github.event_name != 'pull_request' }}
|
||||
SOURCE: registry/add-entry/cmd
|
||||
TARGET: ghcr.io/buildpacks/actions/registry/add-entry
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
|
|
@ -2,14 +2,17 @@ name: Action registry-compute-metadata
|
|||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- registry/*
|
||||
- internal/**
|
||||
- registry/compute-metadata/**
|
||||
- registry/internal/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- registry/*
|
||||
- internal/**
|
||||
- registry/compute-metadata/**
|
||||
- registry/internal/**
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@ name: Action registry-request-add-entry
|
|||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- registry/*
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/request-add-entry/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- registry/*
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/request-add-entry/**
|
||||
release:
|
||||
types:
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@ name: Action registry-request-yank-entry
|
|||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- registry/*
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/request-yank-entry/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- registry/*
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/request-yank-entry/**
|
||||
release:
|
||||
types:
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@ name: Action registry-verify-namespace-owner
|
|||
"on":
|
||||
pull_request:
|
||||
paths:
|
||||
- registry/*
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/verify-namespace-owner/**
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- test
|
||||
paths:
|
||||
- registry/*
|
||||
- internal/**
|
||||
- registry/internal/**
|
||||
- registry/verify-namespace-owner/**
|
||||
release:
|
||||
types:
|
||||
|
|
|
|||
27
README.md
27
README.md
|
|
@ -9,6 +9,7 @@
|
|||
- [Buildpackage](#buildpackage)
|
||||
- [Verify Metadata Action](#verify-metadata-action)
|
||||
- [Registry](#registry)
|
||||
- [Add Entry Action](#add-entry-action)
|
||||
- [Compute Metadata Action](#compute-metadata-action)
|
||||
- [Request Add Entry Action](#request-add-entry-action)
|
||||
- [Request Yank Entry Action](#request-yank-entry-action)
|
||||
|
|
@ -61,6 +62,32 @@ with:
|
|||
## Registry
|
||||
[bri]: https://github.com/buildpacks/registry-index
|
||||
|
||||
### Add Entry Action
|
||||
The `registry/add-entry` adds an entry to the [Buildpack Registry Index][bri].
|
||||
|
||||
```yaml
|
||||
uses: docker://ghcr.io/buildpacks/actions/registry/add-entry
|
||||
with:
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
owner: ${{ env.INDEX_OWNER }}
|
||||
repository: ${{ env.INDEX_REPOSITORY }}
|
||||
namespace: ${{ steps.metadata.outputs.namespace }}
|
||||
name: ${{ steps.metadata.outputs.name }}
|
||||
version: ${{ steps.metadata.outputs.version }}
|
||||
address: ${{ steps.metadata.outputs.address }}
|
||||
```
|
||||
|
||||
#### Inputs <!-- omit in toc -->
|
||||
| Parameter | Description
|
||||
| :-------- | :----------
|
||||
| `token` | A GitHub token with permissions to commit to the registry index repository.
|
||||
| `owner` | The owner name of the registry index repository.
|
||||
| `repository` | The repository name of the registry index repository.
|
||||
| `namespace` | The namespace of the buildpack to register.
|
||||
| `name` | The name of the buildpack to register.
|
||||
| `version` | The version of the buildpack to register.
|
||||
| `address` | The address of the buildpack to register.
|
||||
|
||||
### Compute Metadata Action
|
||||
The `registry/compute-metadata` action parses a [`buildpacks/registry-index`][bri] issue and exposes the contents as output parameters.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package entry
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func AddEntry(tk toolkit.Toolkit, repositories services.RepositoriesService) error {
|
||||
owner, ok := tk.GetInput("owner")
|
||||
if !ok {
|
||||
return toolkit.FailedError("owner must be set")
|
||||
}
|
||||
|
||||
repository, ok := tk.GetInput("repository")
|
||||
if !ok {
|
||||
return toolkit.FailedError("repository must be set")
|
||||
}
|
||||
|
||||
namespace, ok := tk.GetInput("namespace")
|
||||
if !ok {
|
||||
return toolkit.FailedError("namespace must be set")
|
||||
}
|
||||
|
||||
name, ok := tk.GetInput("name")
|
||||
if !ok {
|
||||
return toolkit.FailedError("name must be set")
|
||||
}
|
||||
|
||||
version, ok := tk.GetInput("version")
|
||||
if !ok {
|
||||
return toolkit.FailedError("version must be set")
|
||||
}
|
||||
|
||||
address, ok := tk.GetInput("address")
|
||||
if !ok {
|
||||
return toolkit.FailedError("address must be set")
|
||||
}
|
||||
|
||||
file := index.Path(namespace, name)
|
||||
content, _, _, err := repositories.GetContents(context.Background(), owner, repository, file, nil)
|
||||
if err2, ok := err.(*github.ErrorResponse); ok && err2.Response.StatusCode == http.StatusNotFound {
|
||||
fmt.Printf("New Index: %s\n", name)
|
||||
content = &github.RepositoryContent{}
|
||||
} else if err != nil {
|
||||
return toolkit.FailedErrorf("unable to read index %s\n%w", name, err)
|
||||
}
|
||||
|
||||
s, err := content.GetContent()
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to get index content\n%w", err)
|
||||
}
|
||||
|
||||
entries, err := unmarshalEntries(s)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to unmarshal entries\n%w", err)
|
||||
}
|
||||
|
||||
if contains(entries, namespace, version) {
|
||||
return toolkit.FailedErrorf("index %s already has namespace %s and version %s", name, namespace, version)
|
||||
}
|
||||
|
||||
entries = append(entries, index.Entry{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
Version: version,
|
||||
Address: address,
|
||||
})
|
||||
|
||||
s, err = marshalEntries(entries)
|
||||
if err != nil {
|
||||
return toolkit.FailedErrorf("unable to marshal entries\n%w", err)
|
||||
}
|
||||
|
||||
if _, _, err := repositories.CreateFile(context.Background(), owner, repository, file, &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String(fmt.Sprintf("ADD %s/%s@%s", namespace, name, version)),
|
||||
SHA: content.SHA,
|
||||
Content: []byte(s),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Added %s/%s@%s\nx", namespace, name, version)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func contains(entries []index.Entry, namespace string, version string) bool {
|
||||
for _, e := range entries {
|
||||
if e.Namespace == namespace && e.Version == version {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func marshalEntries(entries []index.Entry) (string, error) {
|
||||
b := &bytes.Buffer{}
|
||||
j := json.NewEncoder(b)
|
||||
|
||||
for _, e := range entries {
|
||||
if err := j.Encode(e); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
return b.String(), nil
|
||||
}
|
||||
|
||||
func unmarshalEntries(content string) ([]index.Entry, error) {
|
||||
var entries []index.Entry
|
||||
|
||||
scanner := bufio.NewScanner(strings.NewReader(content))
|
||||
for scanner.Scan() {
|
||||
var e index.Entry
|
||||
if err := json.Unmarshal(scanner.Bytes(), &e); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries = append(entries, e)
|
||||
}
|
||||
|
||||
return entries, scanner.Err()
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package entry_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
"github.com/sclevine/spec/report"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
entry "github.com/buildpacks/github-actions/registry/add-entry"
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
"github.com/buildpacks/github-actions/registry/internal/services"
|
||||
)
|
||||
|
||||
func TestAddEntry(t *testing.T) {
|
||||
spec.Run(t, "add-entry", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
ExpectWithOffset = NewWithT(t).ExpectWithOffset
|
||||
|
||||
r = &services.MockRepositoriesService{}
|
||||
rOpts *github.RepositoryContentGetOptions
|
||||
tk = &toolkit.MockToolkit{}
|
||||
)
|
||||
|
||||
asJSONString := func(v interface{}) string {
|
||||
b, err := json.Marshal(v)
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
it.Before(func() {
|
||||
tk.On("GetInput", "owner").Return("test-owner", true)
|
||||
tk.On("GetInput", "repository").Return("test-repository", true)
|
||||
tk.On("GetInput", "namespace").Return("test-namespace", true)
|
||||
tk.On("GetInput", "name").Return("test-name", true)
|
||||
tk.On("GetInput", "version").Return("test-version", true)
|
||||
tk.On("GetInput", "address").Return("test-address", true)
|
||||
})
|
||||
|
||||
context("index does not exist", func() {
|
||||
it.Before(func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(nil, nil, nil, &github.ErrorResponse{Response: &http.Response{StatusCode: http.StatusNotFound}})
|
||||
})
|
||||
|
||||
it("creates new index", func() {
|
||||
r.On("CreateFile", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String("ADD test-namespace/test-name@test-version"),
|
||||
Content: []byte(fmt.Sprintf("%s\n", asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
}))),
|
||||
}).
|
||||
Return(nil, nil, nil)
|
||||
|
||||
Expect(entry.AddEntry(tk, r)).To(Succeed())
|
||||
})
|
||||
})
|
||||
|
||||
context("index does exist", func() {
|
||||
|
||||
it("fails if version already exists", func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
})),
|
||||
SHA: github.String("test-sha"),
|
||||
}, nil, nil, nil)
|
||||
|
||||
Expect(entry.AddEntry(tk, r)).
|
||||
To(MatchError("::error ::index test-name already has namespace test-namespace and version test-version"))
|
||||
})
|
||||
|
||||
it("adds entry to index", func() {
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), rOpts).
|
||||
Return(&github.RepositoryContent{
|
||||
Content: github.String(asJSONString(index.Entry{
|
||||
Namespace: "another-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
})),
|
||||
SHA: github.String("test-sha"),
|
||||
}, nil, nil, nil)
|
||||
|
||||
r.On("CreateFile", mock.Anything, "test-owner", "test-repository", filepath.Join("te", "st", "test-namespace_test-name"), &github.RepositoryContentFileOptions{
|
||||
Author: &github.CommitAuthor{
|
||||
Name: github.String("buildpacks-bot"),
|
||||
Email: github.String("cncf-buildpacks-maintainers@lists.cncf.io"),
|
||||
},
|
||||
Message: github.String("ADD test-namespace/test-name@test-version"),
|
||||
Content: []byte(fmt.Sprintf("%s\n%s\n",
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "another-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
}),
|
||||
asJSONString(index.Entry{
|
||||
Namespace: "test-namespace",
|
||||
Name: "test-name",
|
||||
Version: "test-version",
|
||||
Address: "test-address",
|
||||
}),
|
||||
)),
|
||||
SHA: github.String("test-sha"),
|
||||
}).
|
||||
Return(nil, nil, nil)
|
||||
|
||||
Expect(entry.AddEntry(tk, r)).To(Succeed())
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}, spec.Report(report.Terminal{}))
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/google/go-github/v32/github"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/buildpacks/github-actions/internal/toolkit"
|
||||
entry "github.com/buildpacks/github-actions/registry/add-entry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
tk := &toolkit.DefaultToolkit{}
|
||||
|
||||
t, ok := tk.GetInput("token")
|
||||
if !ok {
|
||||
fmt.Println(toolkit.FailedError("token must be specified"))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gh := github.NewClient(oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(&oauth2.Token{AccessToken: t})))
|
||||
|
||||
if err := entry.AddEntry(tk, gh.Repositories); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
package index
|
||||
|
||||
type Index struct {
|
||||
type Entry struct {
|
||||
Namespace string `json:"ns"`
|
||||
Name string
|
||||
Version string
|
||||
Yanked bool
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Yanked bool `json:"yanked"`
|
||||
Address string `json:"addr"`
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package index
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func Path(namespace string, name string) string {
|
||||
var path string
|
||||
|
||||
switch len(name) {
|
||||
case 1:
|
||||
path = "1"
|
||||
case 2:
|
||||
path = "2"
|
||||
case 3:
|
||||
path = filepath.Join("3", name[0:2])
|
||||
default:
|
||||
path = filepath.Join(name[0:2], name[2:4])
|
||||
}
|
||||
|
||||
return filepath.Join(path, filepath.Join(fmt.Sprintf("%s_%s", namespace, name)))
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package index_test
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/sclevine/spec"
|
||||
|
||||
"github.com/buildpacks/github-actions/registry/internal/index"
|
||||
)
|
||||
|
||||
func TestPath(t *testing.T) {
|
||||
spec.Run(t, "path", func(t *testing.T, context spec.G, it spec.S) {
|
||||
var (
|
||||
Expect = NewWithT(t).Expect
|
||||
)
|
||||
|
||||
it("returns path for 1 character name", func() {
|
||||
Expect(index.Path("test-namespace", "a")).To(Equal(filepath.Join("1", "test-namespace_a")))
|
||||
})
|
||||
|
||||
it("returns path for 2 character name", func() {
|
||||
Expect(index.Path("test-namespace", "ab")).To(Equal(filepath.Join("2", "test-namespace_ab")))
|
||||
})
|
||||
|
||||
it("returns path for 3 character name", func() {
|
||||
Expect(index.Path("test-namespace", "abc")).To(Equal(filepath.Join("3", "ab", "test-namespace_abc")))
|
||||
})
|
||||
|
||||
it("returns path for 4+ character name", func() {
|
||||
Expect(index.Path("test-namespace", "abcd")).To(Equal(filepath.Join("ab", "cd", "test-namespace_abcd")))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ var restrictedNamespaces = []string{
|
|||
}
|
||||
|
||||
type Namespace struct {
|
||||
Owners []Owner
|
||||
Owners []Owner `json:"owners"`
|
||||
}
|
||||
|
||||
func IsRestricted(namespace string) bool {
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ const (
|
|||
)
|
||||
|
||||
type Owner struct {
|
||||
ID int64
|
||||
Type string
|
||||
ID int64 `json:"id"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type OwnerPredicate func(Owner) bool
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ func VerifyNamespaceOwner(tk toolkit.Toolkit, organizations services.Organizatio
|
|||
|
||||
s, err := content.GetContent()
|
||||
if err != nil {
|
||||
return toolkit.FailedError("unable to get namespace content")
|
||||
return toolkit.FailedErrorf("unable to get namespace content\n%w", err)
|
||||
}
|
||||
|
||||
var n namespace.Namespace
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ func TestVerifyNamespaceOwner(t *testing.T) {
|
|||
|
||||
context("unknown namespace", func() {
|
||||
it.Before(func() {
|
||||
|
||||
r.On("GetContents", mock.Anything, "test-owner", "test-repository", filepath.Join("v1", "test-namespace.json"), rOpts).
|
||||
Return(nil, nil, nil, &github.ErrorResponse{Response: &http.Response{StatusCode: http.StatusNotFound}})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue