Skip to content

Commit 13f1c1a

Browse files
authored
Merge pull request #972 from timofurrer/feature/repository-file-encoding
resource/gitlab_repository_file: Support auto base64 encoding for content
2 parents 78f3946 + 5d665e5 commit 13f1c1a

File tree

6 files changed

+186
-145
lines changed

6 files changed

+186
-145
lines changed

docs/data-sources/repository_file.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ data "gitlab_repository_file" "example" {
4040

4141
- `blob_id` (String) The blob id.
4242
- `commit_id` (String) The commit id.
43-
- `content` (String) base64 encoded file content. No other encoding is currently supported, because of a [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/342430).
43+
- `content` (String) File content. If the content is not yet base64 encoded, it will be encoded automatically. No other encoding is currently supported, because of a [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/342430).
4444
- `content_sha256` (String) File content sha256 digest.
4545
- `encoding` (String) The file content encoding.
4646
- `file_name` (String) The filename.

docs/resources/repository_file.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ resource "gitlab_repository_file" "this" {
4747
author_name = "Terraform"
4848
commit_message = "feature: add meow file"
4949
}
50+
51+
resource "gitlab_repository_file" "readme" {
52+
project = gitlab_project.this.id
53+
file_path = "readme.txt"
54+
branch = "main"
55+
// content will be auto base64 encoded
56+
content = "Meow goes the cat"
57+
author_email = "[email protected]"
58+
author_name = "Terraform"
59+
commit_message = "feature: add readme file"
60+
}
5061
```
5162

5263
<!-- schema generated by tfplugindocs -->
@@ -56,7 +67,7 @@ resource "gitlab_repository_file" "this" {
5667

5768
- `branch` (String) Name of the branch to which to commit to.
5869
- `commit_message` (String) Commit message.
59-
- `content` (String) base64 encoded file content. No other encoding is currently supported, because of a [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/342430).
70+
- `content` (String) File content. If the content is not yet base64 encoded, it will be encoded automatically. No other encoding is currently supported, because of a [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/342430).
6071
- `file_path` (String) The full path of the file. It must be relative to the root of the project without a leading slash `/`.
6172
- `project` (String) The name or ID of the project.
6273

examples/resources/gitlab_repository_file/resource.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,14 @@ resource "gitlab_repository_file" "this" {
1717
author_name = "Terraform"
1818
commit_message = "feature: add meow file"
1919
}
20+
21+
resource "gitlab_repository_file" "readme" {
22+
project = gitlab_project.this.id
23+
file_path = "readme.txt"
24+
branch = "main"
25+
// content will be auto base64 encoded
26+
content = "Meow goes the cat"
27+
author_email = "[email protected]"
28+
author_name = "Terraform"
29+
commit_message = "feature: add readme file"
30+
}

internal/provider/resource_gitlab_repository_file.go

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,20 @@ func resourceGitlabRepositoryFileCreate(ctx context.Context, d *schema.ResourceD
107107
log.Printf("[DEBUG] gitlab_repository_file: got lock to create %s/%s", project, filePath)
108108

109109
client := meta.(*gitlab.Client)
110+
// NOTE: for backwards-compatibility reasons, we also support an already given base64 encoding,
111+
// otherwise we encode the `content` to base64.
112+
content := d.Get("content").(string)
113+
if _, err := base64.StdEncoding.DecodeString(content); err != nil {
114+
log.Printf("[DEBUG] gitlab_repository_file: given content '%s' is not a valid base64 encoded string, encoding it ...", content)
115+
content = base64.StdEncoding.EncodeToString([]byte(content))
116+
}
110117

111118
options := &gitlab.CreateFileOptions{
112119
Branch: gitlab.String(d.Get("branch").(string)),
113120
Encoding: gitlab.String(encoding),
114121
AuthorEmail: gitlab.String(d.Get("author_email").(string)),
115122
AuthorName: gitlab.String(d.Get("author_name").(string)),
116-
Content: gitlab.String(d.Get("content").(string)),
123+
Content: gitlab.String(content),
117124
CommitMessage: gitlab.String(d.Get("commit_message").(string)),
118125
}
119126
if startBranch, ok := d.GetOk("start_branch"); ok {
@@ -160,6 +167,18 @@ func resourceGitlabRepositoryFileRead(ctx context.Context, d *schema.ResourceDat
160167
return diag.FromErr(err)
161168
}
162169

170+
configContent := d.Get("content").(string)
171+
log.Printf("[DEBUG] gitlab_repository_file: comparing content of %s with %s", repositoryFile.Content, configContent)
172+
// NOTE: for backwards-compatibility reasons, we also support an already given base64 encoding,
173+
// otherwise we encode the `content` to base64.
174+
if _, err := base64.StdEncoding.DecodeString(configContent); err != nil {
175+
// if `content` is config is not a base64 encoded string, we decode the one from the API, too
176+
// in case it's base64 encoded, else we don't decode it.
177+
if decodedContent, err := base64.StdEncoding.DecodeString(repositoryFile.Content); err == nil {
178+
repositoryFile.Content = string(decodedContent)
179+
}
180+
}
181+
163182
d.SetId(resourceGitLabRepositoryFileBuildId(project, branch, repositoryFile.FilePath))
164183
d.Set("branch", repositoryFile.Ref)
165184
stateMap := gitlabRepositoryFileToStateMap(project, repositoryFile)
@@ -189,12 +208,20 @@ func resourceGitlabRepositoryFileUpdate(ctx context.Context, d *schema.ResourceD
189208
Ref: gitlab.String(branch),
190209
}
191210

211+
// NOTE: for backwards-compatibility reasons, we also support an already given base64 encoding,
212+
// otherwise we encode the `content` to base64.
213+
content := d.Get("content").(string)
214+
if _, err := base64.StdEncoding.DecodeString(content); err != nil {
215+
log.Printf("[DEBUG] gitlab_repository_file: given content '%s' is not a valid base64 encoded string, encoding it ...", content)
216+
content = base64.StdEncoding.EncodeToString([]byte(content))
217+
}
218+
192219
updateOptions := &gitlab.UpdateFileOptions{
193220
Branch: gitlab.String(branch),
194221
Encoding: gitlab.String(encoding),
195222
AuthorEmail: gitlab.String(d.Get("author_email").(string)),
196223
AuthorName: gitlab.String(d.Get("author_name").(string)),
197-
Content: gitlab.String(d.Get("content").(string)),
224+
Content: gitlab.String(content),
198225
CommitMessage: gitlab.String(d.Get("commit_message").(string)),
199226
}
200227
if startBranch, ok := d.GetOk("start_branch"); ok {
@@ -276,14 +303,6 @@ func resourceGitlabRepositoryFileDelete(ctx context.Context, d *schema.ResourceD
276303
return nil
277304
}
278305

279-
func validateBase64Content(v interface{}, k string) (we []string, errors []error) {
280-
content := v.(string)
281-
if _, err := base64.StdEncoding.DecodeString(content); err != nil {
282-
errors = append(errors, fmt.Errorf("given repository file content '%s' is not base64 encoded, but must be", content))
283-
}
284-
return
285-
}
286-
287306
func resourceGitLabRepositoryFileParseId(id string) (string, string, string, error) {
288307
parts := strings.SplitN(id, ":", 3)
289308
if len(parts) != 3 {

0 commit comments

Comments
 (0)