├── .gitignore ├── .dockerignore ├── Gemfile ├── screenshots ├── pr.png ├── checker.png └── commits.png ├── Dockerfile ├── fixtures ├── event_pull_requet_labeled.json └── event_issues_comment.json ├── Gemfile.lock ├── CHANGELOG.md ├── lib ├── adapters │ └── comment_adapter.rb ├── services │ └── merge_branch_service.rb └── index.rb ├── action.yml ├── spec └── merge_brach_service_spec.rb └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | spec 2 | fixtures 3 | screenshots 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'octokit' -------------------------------------------------------------------------------- /screenshots/pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devmasx/merge-branch/HEAD/screenshots/pr.png -------------------------------------------------------------------------------- /screenshots/checker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devmasx/merge-branch/HEAD/screenshots/checker.png -------------------------------------------------------------------------------- /screenshots/commits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devmasx/merge-branch/HEAD/screenshots/commits.png -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:2.6.3-alpine 2 | 3 | WORKDIR /action 4 | COPY Gemfile Gemfile.lock /action/ 5 | RUN bundle install 6 | COPY lib /action/lib 7 | 8 | CMD ["ruby", "/action/lib/index.rb"] 9 | -------------------------------------------------------------------------------- /fixtures/event_pull_requet_labeled.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "labeled", 3 | "label": { 4 | "color": "d73a4a", 5 | "default": true, 6 | "description": "Something isn't working", 7 | "id": 1694345561, 8 | "name": "merged in develop", 9 | "node_id": "MDU6TGFiZWwxNjk0MzQ1NTYx", 10 | "url": "https://api.github.com/repos/devmasxtest/test-repository/labels/bug" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.8.0) 5 | public_suffix (>= 2.0.2, < 5.0) 6 | faraday (0.17.0) 7 | multipart-post (>= 1.2, < 3) 8 | multipart-post (2.1.1) 9 | octokit (4.14.0) 10 | sawyer (~> 0.8.0, >= 0.5.3) 11 | public_suffix (4.0.6) 12 | sawyer (0.8.2) 13 | addressable (>= 2.3.5) 14 | faraday (> 0.8, < 2.0) 15 | 16 | PLATFORMS 17 | ruby 18 | 19 | DEPENDENCIES 20 | octokit 21 | 22 | BUNDLED WITH 23 | 1.17.2 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v1.4.0 2 | 3 | - Support Github Enterprise [#15](https://github.com/devmasx/merge-branch/pull/15) 4 | - Bump addressable from 2.7.0 to 2.8.0 [#14](https://github.com/devmasx/merge-branch/pull/14) 5 | 6 | ## v1.3.1 7 | 8 | - Fix, check inputs with empty string values. 9 | 10 | ## v1.3.0 11 | 12 | - Add input github_token, read github token from inputs. 13 | 14 | ## v1.2.0 15 | 16 | - Add input from_branch, perform a git merge for any branch combination. 17 | 18 | ## v1.1.1 19 | 20 | - Validate inputs 21 | 22 | ## v1.1.0 23 | 24 | First relase 25 | 26 | - Merge branch with types labeled, now 27 | -------------------------------------------------------------------------------- /lib/adapters/comment_adapter.rb: -------------------------------------------------------------------------------- 1 | class CommentAdapter 2 | COMMENT_REGEXP = /\/merge to/ 3 | BRANCH_REGEXP = /\merge to ([0-9a-zA-Z'-\/]+)/ 4 | COMMAND_NAME = "/merge" 5 | 6 | def initialize(github_event) 7 | @event = github_event 8 | @comment_message = @event&.dig('comment', 'body') 9 | end 10 | 11 | def valid? 12 | @comment_message && @comment_message =~ COMMENT_REGEXP 13 | end 14 | 15 | def branch_name 16 | match_branch_name(@comment_message) 17 | rescue StandardError => e 18 | raise "Could not find branch name, #{e.message}" 19 | end 20 | 21 | def match_branch_name(str) 22 | arr = str.split(/\s+/) 23 | index = arr.index(COMMAND_NAME) 24 | arr[index + 2] 25 | end 26 | 27 | end -------------------------------------------------------------------------------- /lib/services/merge_branch_service.rb: -------------------------------------------------------------------------------- 1 | class MergeBrachService 2 | attr_reader :inputs, :event 3 | 4 | TYPE_LABELED = "labeled".freeze 5 | TYPE_NOW = "now".freeze 6 | 7 | def self.validate_inputs!(target_branch:, type:, label_name:) 8 | raise "Error: Invalid type" unless [TYPE_LABELED, TYPE_NOW].include?(type) 9 | raise "Error: Empty target branch"unless target_branch 10 | if type == TYPE_LABELED 11 | raise " Error: Empty target label name" unless label_name 12 | end 13 | end 14 | 15 | def initialize(inputs, github_event) 16 | @inputs = inputs 17 | @event = github_event 18 | end 19 | 20 | def valid? 21 | case inputs[:type] 22 | when TYPE_LABELED 23 | labeled_valid? 24 | when TYPE_NOW 25 | true 26 | end 27 | end 28 | 29 | def labeled_valid? 30 | @event&.dig('action') == TYPE_LABELED && 31 | @event&.dig('label', 'name') == inputs[:label_name] 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Merge branch' 2 | description: 'A GitHub Action that manage git merge for any gitflow' 3 | author: Miguel Savignano 4 | inputs: 5 | type: 6 | type: 'labeled | now' 7 | required: false 8 | default: 'labeled' 9 | label_name: 10 | description: 'PR Label name' 11 | required: false 12 | target_branch: 13 | description: 'The name of target branch to merge' 14 | required: true 15 | from_branch: 16 | description: 'Alias head_to_merge input' 17 | required: false 18 | head_to_merge: 19 | description: 'The branch name or hash to merge. default GITHUB_SHA' 20 | required: false 21 | github_token: 22 | description: 'Github token' 23 | required: true 24 | message: 25 | description: 'Commit message' 26 | required: false 27 | disable_fastforwards: 28 | description: 'Does not merge the branch if no files have been changed' 29 | required: false 30 | runs: 31 | using: 'docker' 32 | image: 'Dockerfile' 33 | branding: 34 | icon: 'git-merge' 35 | color: 'purple' 36 | -------------------------------------------------------------------------------- /spec/merge_brach_service_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/services/merge_branch_service' 2 | 3 | describe MergeBrachService do 4 | context "with invalid type" do 5 | let(:inputs) { 6 | { type: 'invalid_type', event: {}, target_branch: 'develop' } 7 | } 8 | 9 | it ".validate_inputs!" do 10 | expect{ MergeBrachService.validate_inputs!(inputs) }.to raise_error() 11 | end 12 | end 13 | 14 | context "with labeled" do 15 | let(:label_name) { 'merge in develop' } 16 | let(:target_branch) { 'develop' } 17 | let(:event) { { 'action' => 'labeled', 'label' => { 'name' => label_name } } } 18 | let(:inputs) { 19 | { type: 'labeled', target_branch: target_branch, label_name: label_name } 20 | } 21 | 22 | context "with valid inputs" do 23 | it ".validate_inputs!" do 24 | expect{ MergeBrachService.validate_inputs!(inputs) }.to_not raise_error() 25 | end 26 | end 27 | 28 | context "with invalid label name" do 29 | let(:label_name) { nil } 30 | 31 | it ".validate_inputs!" do 32 | expect{ MergeBrachService.validate_inputs!(inputs) }.to raise_error() 33 | end 34 | end 35 | 36 | context "not match label" do 37 | let(:event) { { 'action' => 'labeled', 'label' => { 'name' => 'other label' } } } 38 | 39 | it "#valid?" do 40 | service = MergeBrachService.new(inputs, event) 41 | expect(service.valid?).to eq(false) 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/index.rb: -------------------------------------------------------------------------------- 1 | require 'json' 2 | require 'octokit' 3 | require_relative './services/merge_branch_service' 4 | 5 | def presence(value) 6 | return nil if value == "" 7 | value 8 | end 9 | 10 | Octokit.configure do |c| 11 | c.api_endpoint = ENV['GITHUB_API_URL'] 12 | end 13 | 14 | @event = JSON.parse(File.read(ENV['GITHUB_EVENT_PATH'])) 15 | @head_to_merge = presence(ENV['INPUT_HEAD_TO_MERGE']) || presence(ENV['INPUT_FROM_BRANCH']) || presence(ENV['GITHUB_SHA']) # or brach name 16 | @repository = ENV['GITHUB_REPOSITORY'] 17 | @github_token = presence(ENV['INPUT_GITHUB_TOKEN']) || presence(ENV['GITHUB_TOKEN']) 18 | 19 | inputs = { 20 | type: presence(ENV['INPUT_TYPE']) || MergeBrachService::TYPE_LABELED, # labeled | comment | now 21 | label_name: ENV['INPUT_LABEL_NAME'], 22 | target_branch: ENV['INPUT_TARGET_BRANCH'] 23 | } 24 | 25 | MergeBrachService.validate_inputs!(inputs) 26 | service = MergeBrachService.new(inputs, @event) 27 | 28 | if service.valid? 29 | @client = Octokit::Client.new(access_token: @github_token) 30 | 31 | comparison = @client.compare(@repository, inputs[:target_branch], @head_to_merge) 32 | if comparison.status == 'identical' && presence(ENV['INPUT_DISABLE_FASTFORWARDS']) && ENV['INPUT_DISABLE_FASTFORWARDS'] == "true" 33 | puts "Neutral: skip fastforward merge target_branch: #{inputs[:target_branch]} @head_to_merge: #{@head_to_merge}" 34 | else 35 | puts "Running perform merge target_branch: #{inputs[:target_branch]} @head_to_merge: #{@head_to_merge}}" 36 | @client.merge(@repository, inputs[:target_branch], @head_to_merge, ENV['INPUT_MESSAGE'] ? {commit_message: ENV['INPUT_MESSAGE']} : {}) 37 | puts "Completed: Finish merge branch #{@head_to_merge} to #{inputs[:target_branch]}" 38 | end 39 | else 40 | puts "Neutral: skip merge target_branch: #{inputs[:target_branch]} @head_to_merge: #{@head_to_merge}" 41 | end 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Merge branch action 2 | 3 | Runs a git merge in your CI. 4 | 5 | Examples: 6 | 7 | ### Sync branches 8 | 9 | ```yaml 10 | name: Sync multiple branches 11 | on: 12 | push: 13 | branches: 14 | - '*' 15 | jobs: 16 | sync-branch: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@master 20 | 21 | - name: Merge development -> staging 22 | uses: devmasx/merge-branch@master 23 | with: 24 | type: now 25 | from_branch: development 26 | target_branch: staging 27 | github_token: ${{ secrets.GITHUB_TOKEN }} 28 | 29 | - name: Merge staging -> uat 30 | uses: devmasx/merge-branch@master 31 | with: 32 | type: now 33 | from_branch: staging 34 | target_branch: uat 35 | github_token: ${{ secrets.GITHUB_TOKEN }} 36 | ``` 37 | 38 | ### Merge current branch 39 | 40 | ```yaml 41 | name: Merge any release branch to uat 42 | on: 43 | push: 44 | branches: 45 | - 'release/*' 46 | jobs: 47 | merge-branch: 48 | runs-on: ubuntu-latest 49 | steps: 50 | - uses: actions/checkout@master 51 | 52 | - name: Merge staging -> uat 53 | uses: devmasx/merge-branch@master 54 | with: 55 | type: now 56 | target_branch: uat 57 | github_token: ${{ secrets.GITHUB_TOKEN }} 58 | ``` 59 | 60 | ### Merge current branch with commit message 61 | 62 | ```yaml 63 | name: Merge any release branch to uat 64 | on: 65 | push: 66 | branches: 67 | - 'release/*' 68 | jobs: 69 | merge-branch: 70 | runs-on: ubuntu-latest 71 | steps: 72 | - uses: actions/checkout@master 73 | 74 | - name: Merge staging -> uat 75 | uses: devmasx/merge-branch@master 76 | with: 77 | type: now 78 | target_branch: uat 79 | message: Merge staging into uat 80 | github_token: ${{ secrets.GITHUB_TOKEN }} 81 | ``` 82 | 83 | ### On labeled 84 | 85 | Merge pull request branch using GitHub labels. 86 | 87 | When you set a label in a pull request this action can merge the pull request branch to other branch, useful for develop branch or staging environments. 88 | 89 | ![PR](./screenshots/pr.png) 90 | ![Checker](./screenshots/checker.png) 91 | 92 | ```yaml 93 | name: Merge branch with labeled 94 | on: 95 | pull_request: 96 | types: [labeled] 97 | jobs: 98 | merge-branch: 99 | runs-on: ubuntu-latest 100 | steps: 101 | - uses: actions/checkout@master 102 | 103 | - name: Merge by labeled 104 | uses: devmasx/merge-branch@master 105 | with: 106 | label_name: 'merged in develop' 107 | target_branch: 'develop' 108 | github_token: ${{ secrets.GITHUB_TOKEN }} 109 | ``` 110 | -------------------------------------------------------------------------------- /fixtures/event_issues_comment.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": "created", 3 | "comment": { 4 | "author_association": "CONTRIBUTOR", 5 | "body": "my comment /merge to feature/develop-test--12 for test", 6 | "created_at": "2019-11-23T23:40:31Z", 7 | "html_url": "https://github.com/devmasxtest/test-repository/pull/2#issuecomment-557843019", 8 | "id": 557843019, 9 | "issue_url": "https://api.github.com/repos/devmasxtest/test-repository/issues/2", 10 | "node_id": "MDEyOklzc3VlQ29tbWVudDU1Nzg0MzAxOQ==", 11 | "updated_at": "2019-11-23T23:40:31Z", 12 | "url": "https://api.github.com/repos/devmasxtest/test-repository/issues/comments/557843019", 13 | "user": { 14 | "avatar_url": "https://avatars3.githubusercontent.com/u/6641863?v=4", 15 | "events_url": "https://api.github.com/users/MiguelSavignano/events{/privacy}", 16 | "followers_url": "https://api.github.com/users/MiguelSavignano/followers", 17 | "following_url": "https://api.github.com/users/MiguelSavignano/following{/other_user}", 18 | "gists_url": "https://api.github.com/users/MiguelSavignano/gists{/gist_id}", 19 | "gravatar_id": "", 20 | "html_url": "https://github.com/MiguelSavignano", 21 | "id": 6641863, 22 | "login": "MiguelSavignano", 23 | "node_id": "MDQ6VXNlcjY2NDE4NjM=", 24 | "organizations_url": "https://api.github.com/users/MiguelSavignano/orgs", 25 | "received_events_url": "https://api.github.com/users/MiguelSavignano/received_events", 26 | "repos_url": "https://api.github.com/users/MiguelSavignano/repos", 27 | "site_admin": false, 28 | "starred_url": "https://api.github.com/users/MiguelSavignano/starred{/owner}{/repo}", 29 | "subscriptions_url": "https://api.github.com/users/MiguelSavignano/subscriptions", 30 | "type": "User", 31 | "url": "https://api.github.com/users/MiguelSavignano" 32 | } 33 | }, 34 | "issue": { 35 | "assignee": null, 36 | "assignees": [], 37 | "author_association": "CONTRIBUTOR", 38 | "body": "comment in PR", 39 | "closed_at": null, 40 | "comments": 0, 41 | "comments_url": "https://api.github.com/repos/devmasxtest/test-repository/issues/2/comments", 42 | "created_at": "2019-11-23T23:39:35Z", 43 | "events_url": "https://api.github.com/repos/devmasxtest/test-repository/issues/2/events", 44 | "html_url": "https://github.com/devmasxtest/test-repository/pull/2", 45 | "id": 527624442, 46 | "labels": [], 47 | "labels_url": "https://api.github.com/repos/devmasxtest/test-repository/issues/2/labels{/name}", 48 | "locked": false, 49 | "milestone": null, 50 | "node_id": "MDExOlB1bGxSZXF1ZXN0MzQ0ODU1MzQ4", 51 | "number": 2, 52 | "pull_request": { 53 | "diff_url": "https://github.com/devmasxtest/test-repository/pull/2.diff", 54 | "html_url": "https://github.com/devmasxtest/test-repository/pull/2", 55 | "patch_url": "https://github.com/devmasxtest/test-repository/pull/2.patch", 56 | "url": "https://api.github.com/repos/devmasxtest/test-repository/pulls/2" 57 | }, 58 | "repository_url": "https://api.github.com/repos/devmasxtest/test-repository", 59 | "state": "open", 60 | "title": "PR message", 61 | "updated_at": "2019-11-23T23:40:31Z", 62 | "url": "https://api.github.com/repos/devmasxtest/test-repository/issues/2", 63 | "user": { 64 | "avatar_url": "https://avatars3.githubusercontent.com/u/6641863?v=4", 65 | "events_url": "https://api.github.com/users/MiguelSavignano/events{/privacy}", 66 | "followers_url": "https://api.github.com/users/MiguelSavignano/followers", 67 | "following_url": "https://api.github.com/users/MiguelSavignano/following{/other_user}", 68 | "gists_url": "https://api.github.com/users/MiguelSavignano/gists{/gist_id}", 69 | "gravatar_id": "", 70 | "html_url": "https://github.com/MiguelSavignano", 71 | "id": 6641863, 72 | "login": "MiguelSavignano", 73 | "node_id": "MDQ6VXNlcjY2NDE4NjM=", 74 | "organizations_url": "https://api.github.com/users/MiguelSavignano/orgs", 75 | "received_events_url": "https://api.github.com/users/MiguelSavignano/received_events", 76 | "repos_url": "https://api.github.com/users/MiguelSavignano/repos", 77 | "site_admin": false, 78 | "starred_url": "https://api.github.com/users/MiguelSavignano/starred{/owner}{/repo}", 79 | "subscriptions_url": "https://api.github.com/users/MiguelSavignano/subscriptions", 80 | "type": "User", 81 | "url": "https://api.github.com/users/MiguelSavignano" 82 | } 83 | }, 84 | "organization": { 85 | "avatar_url": "https://avatars2.githubusercontent.com/u/45522007?v=4", 86 | "description": null, 87 | "events_url": "https://api.github.com/orgs/devmasxtest/events", 88 | "hooks_url": "https://api.github.com/orgs/devmasxtest/hooks", 89 | "id": 45522007, 90 | "issues_url": "https://api.github.com/orgs/devmasxtest/issues", 91 | "login": "devmasxtest", 92 | "members_url": "https://api.github.com/orgs/devmasxtest/members{/member}", 93 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ1NTIyMDA3", 94 | "public_members_url": "https://api.github.com/orgs/devmasxtest/public_members{/member}", 95 | "repos_url": "https://api.github.com/orgs/devmasxtest/repos", 96 | "url": "https://api.github.com/orgs/devmasxtest" 97 | }, 98 | "repository": { 99 | "archive_url": "https://api.github.com/repos/devmasxtest/test-repository/{archive_format}{/ref}", 100 | "archived": false, 101 | "assignees_url": "https://api.github.com/repos/devmasxtest/test-repository/assignees{/user}", 102 | "blobs_url": "https://api.github.com/repos/devmasxtest/test-repository/git/blobs{/sha}", 103 | "branches_url": "https://api.github.com/repos/devmasxtest/test-repository/branches{/branch}", 104 | "clone_url": "https://github.com/devmasxtest/test-repository.git", 105 | "collaborators_url": "https://api.github.com/repos/devmasxtest/test-repository/collaborators{/collaborator}", 106 | "comments_url": "https://api.github.com/repos/devmasxtest/test-repository/comments{/number}", 107 | "commits_url": "https://api.github.com/repos/devmasxtest/test-repository/commits{/sha}", 108 | "compare_url": "https://api.github.com/repos/devmasxtest/test-repository/compare/{base}...{head}", 109 | "contents_url": "https://api.github.com/repos/devmasxtest/test-repository/contents/{+path}", 110 | "contributors_url": "https://api.github.com/repos/devmasxtest/test-repository/contributors", 111 | "created_at": "2019-11-23T21:36:13Z", 112 | "default_branch": "master", 113 | "deployments_url": "https://api.github.com/repos/devmasxtest/test-repository/deployments", 114 | "description": "Test github actions, merge actions, comments, PR etc...", 115 | "disabled": false, 116 | "downloads_url": "https://api.github.com/repos/devmasxtest/test-repository/downloads", 117 | "events_url": "https://api.github.com/repos/devmasxtest/test-repository/events", 118 | "fork": false, 119 | "forks": 0, 120 | "forks_count": 0, 121 | "forks_url": "https://api.github.com/repos/devmasxtest/test-repository/forks", 122 | "full_name": "devmasxtest/test-repository", 123 | "git_commits_url": "https://api.github.com/repos/devmasxtest/test-repository/git/commits{/sha}", 124 | "git_refs_url": "https://api.github.com/repos/devmasxtest/test-repository/git/refs{/sha}", 125 | "git_tags_url": "https://api.github.com/repos/devmasxtest/test-repository/git/tags{/sha}", 126 | "git_url": "git://github.com/devmasxtest/test-repository.git", 127 | "has_downloads": true, 128 | "has_issues": true, 129 | "has_pages": false, 130 | "has_projects": true, 131 | "has_wiki": true, 132 | "homepage": null, 133 | "hooks_url": "https://api.github.com/repos/devmasxtest/test-repository/hooks", 134 | "html_url": "https://github.com/devmasxtest/test-repository", 135 | "id": 223656250, 136 | "issue_comment_url": "https://api.github.com/repos/devmasxtest/test-repository/issues/comments{/number}", 137 | "issue_events_url": "https://api.github.com/repos/devmasxtest/test-repository/issues/events{/number}", 138 | "issues_url": "https://api.github.com/repos/devmasxtest/test-repository/issues{/number}", 139 | "keys_url": "https://api.github.com/repos/devmasxtest/test-repository/keys{/key_id}", 140 | "labels_url": "https://api.github.com/repos/devmasxtest/test-repository/labels{/name}", 141 | "language": null, 142 | "languages_url": "https://api.github.com/repos/devmasxtest/test-repository/languages", 143 | "license": null, 144 | "merges_url": "https://api.github.com/repos/devmasxtest/test-repository/merges", 145 | "milestones_url": "https://api.github.com/repos/devmasxtest/test-repository/milestones{/number}", 146 | "mirror_url": null, 147 | "name": "test-repository", 148 | "node_id": "MDEwOlJlcG9zaXRvcnkyMjM2NTYyNTA=", 149 | "notifications_url": "https://api.github.com/repos/devmasxtest/test-repository/notifications{?since,all,participating}", 150 | "open_issues": 1, 151 | "open_issues_count": 1, 152 | "owner": { 153 | "avatar_url": "https://avatars2.githubusercontent.com/u/45522007?v=4", 154 | "events_url": "https://api.github.com/users/devmasxtest/events{/privacy}", 155 | "followers_url": "https://api.github.com/users/devmasxtest/followers", 156 | "following_url": "https://api.github.com/users/devmasxtest/following{/other_user}", 157 | "gists_url": "https://api.github.com/users/devmasxtest/gists{/gist_id}", 158 | "gravatar_id": "", 159 | "html_url": "https://github.com/devmasxtest", 160 | "id": 45522007, 161 | "login": "devmasxtest", 162 | "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ1NTIyMDA3", 163 | "organizations_url": "https://api.github.com/users/devmasxtest/orgs", 164 | "received_events_url": "https://api.github.com/users/devmasxtest/received_events", 165 | "repos_url": "https://api.github.com/users/devmasxtest/repos", 166 | "site_admin": false, 167 | "starred_url": "https://api.github.com/users/devmasxtest/starred{/owner}{/repo}", 168 | "subscriptions_url": "https://api.github.com/users/devmasxtest/subscriptions", 169 | "type": "Organization", 170 | "url": "https://api.github.com/users/devmasxtest" 171 | }, 172 | "private": false, 173 | "pulls_url": "https://api.github.com/repos/devmasxtest/test-repository/pulls{/number}", 174 | "pushed_at": "2019-11-23T23:39:36Z", 175 | "releases_url": "https://api.github.com/repos/devmasxtest/test-repository/releases{/id}", 176 | "size": 1, 177 | "ssh_url": "git@github.com:devmasxtest/test-repository.git", 178 | "stargazers_count": 0, 179 | "stargazers_url": "https://api.github.com/repos/devmasxtest/test-repository/stargazers", 180 | "statuses_url": "https://api.github.com/repos/devmasxtest/test-repository/statuses/{sha}", 181 | "subscribers_url": "https://api.github.com/repos/devmasxtest/test-repository/subscribers", 182 | "subscription_url": "https://api.github.com/repos/devmasxtest/test-repository/subscription", 183 | "svn_url": "https://github.com/devmasxtest/test-repository", 184 | "tags_url": "https://api.github.com/repos/devmasxtest/test-repository/tags", 185 | "teams_url": "https://api.github.com/repos/devmasxtest/test-repository/teams", 186 | "trees_url": "https://api.github.com/repos/devmasxtest/test-repository/git/trees{/sha}", 187 | "updated_at": "2019-11-23T23:38:21Z", 188 | "url": "https://api.github.com/repos/devmasxtest/test-repository", 189 | "watchers": 0, 190 | "watchers_count": 0 191 | }, 192 | "sender": { 193 | "avatar_url": "https://avatars3.githubusercontent.com/u/6641863?v=4", 194 | "events_url": "https://api.github.com/users/MiguelSavignano/events{/privacy}", 195 | "followers_url": "https://api.github.com/users/MiguelSavignano/followers", 196 | "following_url": "https://api.github.com/users/MiguelSavignano/following{/other_user}", 197 | "gists_url": "https://api.github.com/users/MiguelSavignano/gists{/gist_id}", 198 | "gravatar_id": "", 199 | "html_url": "https://github.com/MiguelSavignano", 200 | "id": 6641863, 201 | "login": "MiguelSavignano", 202 | "node_id": "MDQ6VXNlcjY2NDE4NjM=", 203 | "organizations_url": "https://api.github.com/users/MiguelSavignano/orgs", 204 | "received_events_url": "https://api.github.com/users/MiguelSavignano/received_events", 205 | "repos_url": "https://api.github.com/users/MiguelSavignano/repos", 206 | "site_admin": false, 207 | "starred_url": "https://api.github.com/users/MiguelSavignano/starred{/owner}{/repo}", 208 | "subscriptions_url": "https://api.github.com/users/MiguelSavignano/subscriptions", 209 | "type": "User", 210 | "url": "https://api.github.com/users/MiguelSavignano" 211 | } 212 | } 213 | --------------------------------------------------------------------------------