1
1
# ' Retrieve the content of a file from a GitHub repository
2
2
# '
3
- # ' @param repo Character string specifying the full name of the repository (owner/repo)
4
- # ' @param path Character string specifying the path to the file
5
- # ' @param ref Character string specifying the branch name or commit SHA. Default is NULL.
3
+ # ' This function fetches a file from a GitHub repository and returns its content and SHA.
4
+ # ' If the file cannot be retrieved, it returns NULL and optionally displays a warning message.
5
+ # '
6
+ # ' @param repo Character string specifying the full name of the repository (format: "owner/repo")
7
+ # ' @param path Character string specifying the path to the file within the repository
8
+ # ' @param ref Character string specifying the branch name, tag, or commit SHA. Default is NULL (uses default branch).
9
+ # '
10
+ # ' @return
11
+ # ' When successful, returns a `list` with two elements:
12
+ # '
13
+ # ' \describe{
14
+ # ' \item{content}{Character string containing the decoded file content}
15
+ # ' \item{sha}{Character string with the file's blob SHA for use in update operations}
16
+ # ' }
17
+ # '
18
+ # ' When the file cannot be retrieved (e.g., does not exist or no access), returns `NULL`.
6
19
# '
7
- # ' @return List with the content and SHA of the file if it exists, NULL otherwise
8
20
# ' @export
9
21
# '
10
- # ' @examples
11
- # ' \dontrun{
12
- # ' file_info <- file_content("username/repo", "path/to/file.R")
22
+ # ' @examplesIf interactive()
23
+ # ' # Get content from default branch
24
+ # ' file_info <- file_content("username/repository", "path/to/file.R")
25
+ # ' if (!is.null(file_info)) {
26
+ # ' # Access the content and SHA
27
+ # ' content <- file_info$content
28
+ # ' sha <- file_info$sha
13
29
# ' }
14
- file_content <- function (repo , path , ref = NULL , quiet = FALSE ) {
30
+ # '
31
+ # ' # Get content from specific branch
32
+ # ' file_info <- file_content("username/repository", "path/to/file.R", ref = "develop")
33
+ # '
34
+ # ' # Suppress warnings
35
+ # ' file_info <- file_content("username/repository", "path/to/file.R")
36
+ file_content <- function (repo , path , ref = NULL ) {
15
37
tryCatch({
16
38
query <- list (path = path )
17
39
if (! is.null(ref )) {
@@ -33,28 +55,62 @@ file_content <- function(repo, path, ref = NULL, quiet = FALSE) {
33
55
return (NULL )
34
56
}
35
57
}, error = function (e ) {
36
- if (! quiet ) {
37
- cli :: cli_alert_warning(" Could not fetch file {.file {path}} from {.val {repo}}: {e$message}" )
38
- }
58
+ cli :: cli_alert_warning(" Could not fetch file {.file {path}} from {.val {repo}}: {e$message}" )
39
59
return (NULL )
40
60
})
41
61
}
42
62
43
63
# ' Create or update a file in a GitHub repository
44
64
# '
45
- # ' @param repo Character string specifying the full name of the repository (owner/repo)
46
- # ' @param path Character string specifying the path to the file
65
+ # ' This function creates a new file or updates an existing file in a GitHub repository.
66
+ # ' For updating existing files, the SHA of the current file must be provided.
67
+ # '
68
+ # ' @param repo Character string specifying the full name of the repository (format: "owner/repo")
69
+ # ' @param path Character string specifying the path to the file within the repository
47
70
# ' @param content Character string with the new content of the file
48
71
# ' @param message Character string with the commit message
49
72
# ' @param branch Character string specifying the branch name. Default is NULL (uses default branch).
50
- # ' @param sha Character string with the blob SHA of the file being replaced (required for updates). Default is NULL.
73
+ # ' @param sha Character string with the blob SHA of the file being replaced. Required for updating
74
+ # ' existing files; omit for creating new files. Default is NULL.
75
+ # ' @param quiet Logical; if TRUE, suppresses progress and status messages. Default is FALSE.
76
+ # '
77
+ # ' @return
78
+ # ' When successful, returns a `list` containing the GitHub API response with details about the commit,
79
+ # ' including:
80
+ # '
81
+ # ' \describe{
82
+ # ' \item{content}{Information about the updated file}
83
+ # ' \item{commit}{Details about the created commit}
84
+ # ' }
85
+ # '
86
+ # ' When the operation fails (e.g., permission issues, invalid SHA), returns `NULL`.
51
87
# '
52
- # ' @return A list with the API response or NULL if operation failed
53
88
# ' @export
54
89
# '
55
- # ' @examples
56
- # ' \dontrun{
57
- # ' result <- file_update("username/repo", "path/to/file.R", "new content", "Update file")
90
+ # ' @examplesIf interactive()
91
+ # ' # Create a new file
92
+ # ' result <- file_update(
93
+ # ' repo = "username/repository",
94
+ # ' path = "path/to/new_file.R",
95
+ # ' content = "# New R script\n\nprint('Hello world')",
96
+ # ' message = "Add new script file"
97
+ # ' )
98
+ # ' # Check if operation was successful
99
+ # ' if (!is.null(result)) {
100
+ # ' # Access commit information
101
+ # ' commit_sha <- result$commit$sha
102
+ # ' }
103
+ # '
104
+ # ' # Update an existing file (requires SHA)
105
+ # ' file_info <- file_content("username/repository", "path/to/existing_file.R")
106
+ # ' if (!is.null(file_info)) {
107
+ # ' result <- file_update(
108
+ # ' repo = "username/repository",
109
+ # ' path = "path/to/existing_file.R",
110
+ # ' content = "# Updated content\n\nprint('Hello updated world')",
111
+ # ' message = "Update file content",
112
+ # ' sha = file_info$sha
113
+ # ' )
58
114
# ' }
59
115
file_update <- function (repo , path , content , message , branch = NULL , sha = NULL , quiet = FALSE ) {
60
116
tryCatch({
@@ -84,7 +140,6 @@ file_update <- function(repo, path, content, message, branch = NULL, sha = NULL,
84
140
),
85
141
query
86
142
))
87
-
88
143
if (! quiet ) {
89
144
if (operation == " create" ) {
90
145
cli :: cli_alert_success(" Created file {.file {path}} in {.val {repo}}" )
@@ -97,31 +152,55 @@ file_update <- function(repo, path, content, message, branch = NULL, sha = NULL,
97
152
98
153
}, error = function (e ) {
99
154
operation_name <- ifelse(is.null(sha ), " creating" , " updating" )
100
- if (! quiet ) {
101
- cli :: cli_alert_danger(" Error {operation_name} file {.file {path}} in {.val {repo}}: {e$message}" )
102
- }
155
+ cli :: cli_alert_danger(" Error {operation_name} file {.file {path}} in {.val {repo}}: {e$message}" )
103
156
return (NULL )
104
157
})
105
158
}
106
159
107
160
# ' Deploy a file to multiple GitHub repositories
108
161
# '
162
+ # ' This function deploys a local file to multiple GitHub repositories. It can create new files
163
+ # ' or update existing ones, and provides detailed status reporting for each operation.
164
+ # '
109
165
# ' @param source_file Character string specifying the local file path to deploy
110
166
# ' @param target_path Character string specifying the path in the repositories where the file should be placed
111
- # ' @param repos Data frame of repositories as returned by repos()
112
- # ' @param commit_message Character string with the commit message. Default uses a standard message.
167
+ # ' @param repos Data frame of repositories as returned by ` repos()` function, with at least a `full_name` column
168
+ # ' @param commit_message Character string with the commit message. Default automatically generates a message.
113
169
# ' @param branch Character string specifying the branch name. Default is NULL (uses default branch).
114
170
# ' @param create_if_missing Logical indicating whether to create the file if it doesn't exist. Default is TRUE.
115
- # ' @param dry_run Logical indicating whether to only simulate the changes without actually making them. Default is FALSE.
171
+ # ' @param dry_run Logical indicating whether to only simulate the changes without making actual commits. Default is FALSE.
172
+ # ' @param quiet Logical; if TRUE, suppresses progress and status messages. Default is FALSE.
173
+ # '
174
+ # ' @return
175
+ # ' Returns a `data.frame` with class `"file_deploy_result"` containing the following columns:
176
+ # '
177
+ # ' \describe{
178
+ # ' \item{repository}{Character, the full repository name (owner/repo)}
179
+ # ' \item{status}{Character, indicating the operation result with one of these values:
180
+ # ' "created", "updated", "unchanged", "skipped", "error", "would_create", "would_update"}
181
+ # ' \item{message}{Character, a description of the action taken or error encountered}
182
+ # ' }
183
+ # '
184
+ # ' @seealso [`print.file_deploy_result()`] for a formatted summary of deployment results.
116
185
# '
117
- # ' @return A data frame with the results of each deployment
118
186
# ' @export
119
187
# '
120
- # ' @examples
121
- # ' \dontrun{
122
- # ' repositories <- repos("myorg")
123
- # ' results <- file_deploy("local/path/to/file.R", ".github/workflows/ci.yml", repositories)
124
- # ' }
188
+ # ' @examplesIf interactive()
189
+ # ' # Get list of repositories
190
+ # ' repositories <- repos("my-organization")
191
+ # '
192
+ # ' # Deploy a workflow file to all repositories
193
+ # ' results <- file_deploy(
194
+ # ' source_file = "local/path/to/workflow.yml",
195
+ # ' target_path = ".github/workflows/ci.yml",
196
+ # ' repos = repositories
197
+ # ' )
198
+ # '
199
+ # ' # Filter to see only successfully updated repositories
200
+ # ' updated <- results[results$status == "updated", ]
201
+ # '
202
+ # ' # Check for any errors
203
+ # ' errors <- results[results$status == "error", ]
125
204
file_deploy <- function (source_file , target_path , repos ,
126
205
commit_message = NULL , branch = NULL ,
127
206
create_if_missing = TRUE , dry_run = FALSE , quiet = FALSE ) {
@@ -134,7 +213,7 @@ file_deploy <- function(source_file, target_path, repos,
134
213
file_content <- readChar(source_file , file.info(source_file )$ size )
135
214
136
215
if (is.null(commit_message )) {
137
- commit_message <- sprintf(" Update %s via multi.gh automated deployment" , target_path )
216
+ commit_message <- sprintf(" Update %s via multideploy automated deployment" , target_path )
138
217
}
139
218
140
219
# Initialize results data frame
@@ -215,19 +294,30 @@ file_deploy <- function(source_file, target_path, repos,
215
294
return (results )
216
295
}
217
296
218
- # ' Print method for file_deploy_result objects
297
+ # ' Print method for `"file_deploy_result"` objects
298
+ # '
299
+ # ' This method provides a formatted summary of file deployment results,
300
+ # ' showing counts by status and details for any errors encountered.
219
301
# '
220
- # ' @param x The file_deploy_result object to print
221
- # ' @param ... Additional arguments to pass to print methods
302
+ # ' @param x An object of class `"file_deploy_result"` as returned by `file_deploy()`
303
+ # ' @param ... Additional arguments passed to other print methods (not used)
304
+ # '
305
+ # ' @return
306
+ # ' Invisibly returns the original input data frame unchanged.
307
+ # '
308
+ # ' Displays a formatted summary of deployment results to the console.
222
309
# '
223
- # ' @return Invisibly returns the input data frame
224
310
# ' @export
225
311
# '
226
- # ' @examples
227
- # ' \dontrun{
228
- # ' results <- file_deploy("local/file.R", "remote/file.R", repos)
312
+ # ' @examplesIf interactive()
313
+ # ' # Get list of repositories
314
+ # ' repositories <- repos("my-organization")
315
+ # '
316
+ # ' # Deploy files
317
+ # ' results <- file_deploy("local/file.R", "remote/file.R", repositories)
318
+ # '
319
+ # ' # Explicitly print the summary
229
320
# ' print(results)
230
- # ' }
231
321
print.file_deploy_result <- function (x , ... ) {
232
322
# Summary
233
323
status_counts <- table(x $ status )
0 commit comments