Skip to content

Instantly share code, notes, and snippets.

@jeffdonthemic
Last active June 10, 2020 14:49
Show Gist options
  • Save jeffdonthemic/29bb072984b8cdacbdd6d240b02b4cad to your computer and use it in GitHub Desktop.
Save jeffdonthemic/29bb072984b8cdacbdd6d240b02b4cad to your computer and use it in GitHub Desktop.
Delete a file using signed commits
# This code is based upon the following links:
# https://developer.github.com/v3/git/trees/
# https://github.com/testcollab/rails-test
# https://stackoverflow.com/questions/23637961/how-do-i-mark-a-file-as-deleted-in-a-tree-using-the-github-api
# https://github.community/t/deleting-files-via-trees-no-longer-works/14042
# This creates a signed commit on the correct branch, but there are 0 changed files.
# THIS IS THE METHOD THAT IS CALLED BY THE MAIN PROCESS TO REMOVE FILES
def commit_files_to_remove
last_commit_sha = last_commit_from_branch # get last commit
last_tree_sha = tree_sha_for(last_commit_sha) # get base tree
clean_tree = github.git_data.trees.create @repo.username, @repo.repo_name,
tree: clean_branch_badge_tree_files(new_branch_sha),
base_tree: last_tree_sha
# RESPONSE WRITTEN TO 'clean_tree.txt'
body = { message: 'Remove evaluation.json',
tree: clean_tree.sha,
parents: [last_commit_sha],
author: commit_author,
committer: commit_author,
signature: signature(tree_sha: clean_tree.sha, parent_sha: last_commit_sha) }
resp = Faraday.post(commit_url, body.to_json, commit_headers)
commit = JSON.parse(resp.body)
# RESPONSE WRITTEN TO 'commit.txt'
github.git_data.references.update @repo.username, @repo.repo_name,
"heads/#{branch_name}",
sha: commit['sha']
# RESPONSE WRITTEN TO 'update_reference.txt'
end
def last_commit_from_branch
resp = Faraday.get("https://api.github.com/repos/#{@repo.username}/#{@repo.repo_name}/git/ref/heads/#{branch_name}",
nil,
commit_headers)
# RESPONSE WRITTEN TO 'last_commit_from_branch.txt'
JSON.parse(resp.body)['object']['sha']
end
def tree_sha_for(commit_sha)
resp = Faraday.get("https://api.github.com/repos/#{@repo.username}/#{@repo.repo_name}/git/commits/#{commit_sha}",
nil,
commit_headers)
# RESPONSE WRITTEN TO 'tree_sha_for.txt'
JSON.parse(resp.body)['tree']['sha']
end
def clean_branch_badge_tree_files(sha)
# get the base branch tree that has all of the files in it
branch_tree = github.git_data.trees.get @repo.username,
@repo.repo_name,
sha,
recursive: true
# RESPONSE WRITTEN TO 'branch_tree.txt'
# select only the files in a matching subdirectory
badge_tree_files = branch_tree.tree.select { |f| f['path'].include?("/#{api_name}/") }
# exclude any evaluation.json file(s) from the tree to delete
badge_tree_files.reject { |f| f['path'].end_with?('evaluation.json') }
# badge_tree_files FILES WRITTEN TO 'clean_branch_badge_tree_files.txt'
end
def new_branch_sha
@new_branch_sha ||= find_branch_sha(branch_name)
end
def find_branch_sha(branch_name)
refs = github.git_data.references.list @repo.username, @repo.repo_name
results = refs.select { |r| r.ref.eql?("refs/heads/#{branch_name}") }
results.first.object.sha
rescue NoMethodError
raise "Github branch '#{branch_name}' not found."
end
def commit_url
"https://api.github.com/repos/#{@repo.username}/#{@repo.repo_name}/git/commits"
end
def commit_headers
{'Content-Type' => 'application/json', 'Authorization' => "token #{@repo.token}"}
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment