Commit e10b0f05 authored by Robert Schilling's avatar Robert Schilling

Merge branch 'master' into 'api-notes-entity-fields'

# Conflicts:
#   doc/api/v3_to_v4.md
parents 8a1b340f af03dd22
Please view this file on the master branch, on stable branches it's out of date.
## 8.17.0 (2017-02-22)
- Read-only "auditor" user role. !998
- Also reset approvals on push when merge request is closed. !1051
- Copy commit SHA to clipboard. !1066
- Pull EE specific Gitlab::Auth code in to its own module. !1112
- Geo: Added `gitlab:geo:check` and improved `gitlab:envinfo` rake tasks. !1120
- Geo: send the new event type with the backfill function. !1157
- Re-add removed params from projects and issues V3 API. !1209
- Add configurable minimum mirror sync time in admin section. !1217
- Move RepositoryUpdateRemoteMirrorWorker jobs to project_mirror Sidekiq queue. !1234
- Change Builds word to Pipelines in Mirror settings page.
- Fix bundle tag in anaytics page.
- Support v4 API for GitLab Geo endpoints.
- Fixed merge request environment link not displaying.
- Reduce queries needed to check if node is a primary or secondary Geo node.
- Allow squashing merge requests into a single commit.
## 8.16.6 (2017-02-17)
- Geo: send the new event type with the backfill function. !1157
......
......@@ -2,6 +2,187 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 8.17.0 (2017-02-22)
- API: Fix file downloading. !0 (8267)
- Read true-up info from license and validate it. !1159
- Changed composer installer script in the CI PHP example doc. !4342 (Jeffrey Cafferata)
- Display fullscreen button on small screens. !5302 (winniehell)
- Add system hook for when a project is updated (other than rename/transfer). !5711 (Tommy Beadle)
- Fix notifications when set at group level. !6813 (Alexandre Maia)
- Project labels can now be promoted to group labels. !7242 (Olaf Tomalka)
- use webpack to bundle frontend assets and use karma for frontend testing. !7288
- Adds back ability to stop all environments. !7379
- Added labels empty state. !7443
- Add ability to define a coverage regex in the .gitlab-ci.yml. !7447 (Leandro Camargo)
- Disable automatic login after clicking email confirmation links. !7472
- Search feature: redirects to commit page if query is commit sha and only commit found. !8028 (YarNayar)
- Create a TODO for user who set auto-merge when a build fails, merge conflict occurs. !8056 (twonegatives)
- Don't group issues by project on group-level and dashboard issue indexes. !8111 (Bernardo Castro)
- Mark MR as WIP when pushing WIP commits. !8124 (Jurre Stender @jurre)
- Flag multiple empty lines in eslint, fix offenses. !8137
- Add sorting pipeline for a commit. !8319 (Takuya Noguchi)
- Adds service trigger events to api. !8324
- Update pipeline and commit links when CI status is updated. !8351
- Hide version check image if there is no internet connection. !8355 (Ken Ding)
- Prevent removal of input fields if it is the parent dropdown element. !8397
- Introduce maximum session time for terminal websocket connection. !8413
- Allow creating protected branches when user can merge to such branch. !8458
- Refactor MergeRequests::BuildService. !8462 (Rydkin Maxim)
- Added GitLab Pages to CE. !8463
- Support notes when a project is not specified (personal snippet notes). !8468
- Use warning icon in mini-graph if stage passed conditionally. !8503
- Don’t count tasks that are not defined as list items correctly. !8526
- Reformat messages ChatOps. !8528
- Copy commit SHA to clipboard. !8547
- Improve button accessibility on pipelines page. !8561
- Display project ID in project settings. !8572 (winniehell)
- PlantUML support for Markdown. !8588 (Horacio Sanson)
- Fix reply by email without sub-addressing for some clients from Microsoft and Apple. !8620
- Fix nested tasks in ordered list. !8626
- Fix Sort by Recent Sign-in in Admin Area. !8637 (Poornima M)
- Avoid repeated dashes in $CI_ENVIRONMENT_SLUG. !8638
- Only show Merge Request button when user can create a MR. !8639
- Prevent copying of line numbers in parallel diff view. !8706
- Improve build policy and access abilities. !8711
- API: Remove /projects/:id/keys/.. endpoints. !8716 (Robert Schilling)
- API: Remove deprecated 'expires_at' from project snippets. !8723 (Robert Schilling)
- Add `copy` backup strategy to combat file changed errors. !8728
- adds avatar for discussion note. !8734
- Add link verification to badge partial in order to render a badge without a link. !8740
- Reduce hits to LDAP on Git HTTP auth by reordering auth mechanisms. !8752
- prevent diff unfolding link from appearing when there are no more lines to show. !8761
- Redesign searchbar in admin project list. !8776
- Rename Builds to Pipelines, CI/CD Pipelines, or Jobs everywhere. !8787
- dismiss sidebar on repo buttons click. !8798 (Adam Pahlevi)
- fixed small mini pipeline graph line glitch. !8804
- Make all system notes lowercase. !8807
- Support unauthenticated LFS object downloads for public projects. !8824 (Ben Boeckel)
- Add read-only full_path and full_name attributes to Group API. !8827
- allow relative url change without recompiling frontend assets. !8831
- Use vue.js Pipelines table in commit and merge request view. !8844
- Use reCaptcha when an issue is identified as a spam. !8846
- resolve deprecation warnings. !8855 (Adam Pahlevi)
- Cop for gem fetched from a git source. !8856 (Adam Pahlevi)
- Remove flash warning from login page. !8864 (Gerald J. Padilla)
- Adds documentation for how to use Vue.js. !8866
- Add 'View on [env]' link to blobs and individual files in diffs. !8867
- Replace word user with member. !8872
- Change the reply shortcut to focus the field even without a selection. !8873 (Brian Hall)
- Unify MR diff file button style. !8874
- Unify projects search by removing /projects/:search endpoint. !8877
- Fix disable storing of sensitive information when importing a new repo. !8885 (Bernard Pietraga)
- Fix pipeline graph vertical spacing in Firefox and Safari. !8886
- Fix filtered search user autocomplete for gitlab instances that are hosted on a subdirectory. !8891
- Fix Ctrl+Click support for Todos and Merge Request page tabs. !8898
- Fix wrong call to ProjectCacheWorker.perform. !8910
- Don't perform Devise trackable updates on blocked User records. !8915
- Add ability to export project inherited group members to Import/Export. !8923
- replace `find_with_namespace` with `find_by_full_path`. !8949 (Adam Pahlevi)
- Fixes flickering of avatar border in mention dropdown. !8950
- Remove unnecessary queries for .atom and .json in Dashboard::ProjectsController#index. !8956
- Fix deleting projects with pipelines and builds. !8960
- Fix broken anchor links when special characters are used. !8961 (Andrey Krivko)
- Ensure autogenerated title does not cause failing spec. !8963 (brian m. carlson)
- Update doc for enabling or disabling GitLab CI. !8965 (Takuya Noguchi)
- Remove deprecated MR and Issue endpoints and preserve V3 namespace. !8967
- Fixed "substract" typo on /help/user/project/slash_commands. !8976 (Jason Aquino)
- Preserve backward compatibility CI/CD and disallow setting `coverage` regexp in global context. !8981
- use babel to transpile all non-vendor javascript assets regardless of file extension. !8988
- Fix MR widget url. !8989
- Fixes hover cursor on pipeline pagenation. !9003
- Layer award emoji dropdown over the right sidebar. !9004
- Do not display deploy keys in user's own ssh keys list. !9024
- upgrade babel 5.8.x to babel 6.22.x. !9072
- upgrade to webpack v2.2. !9078
- Trigger autocomplete after selecting a slash command. !9117
- Add space between text and loading icon in Megre Request Widget. !9119
- Fix job to pipeline renaming. !9147
- Replace static fixture for merge_request_tabs_spec.js. !9172 (winniehell)
- Replace static fixture for right_sidebar_spec.js. !9211 (winniehell)
- Show merge errors in merge request widget. !9229
- Increase process_commit queue weight from 2 to 3. !9326 (blackst0ne)
- Don't require lib/gitlab/request_profiler/middleware.rb in config/initializers/request_profiler.rb.
- Force new password after password reset via API. (George Andrinopoulos)
- Allows to search within project by commit hash. (YarNayar)
- Show organisation membership and delete comment on smaller viewports, plus change comment author name to username.
- Remove turbolinks.
- Convert pipeline action icons to svg to have them propperly positioned.
- Remove rogue scrollbars for issue comments with inline elements.
- Align Segoe UI label text.
- Color + and - signs in diffs to increase code legibility.
- Fix tab index order on branch commits list page. (Ryan Harris)
- Add hover style to copy icon on commit page header. (Ryan Harris)
- Remove hover animation from row elements.
- Improve pipeline status icon linking in widgets.
- Fix commit title bar and repository view copy clipboard button order on last commit in repository view.
- Fix mini-pipeline stage tooltip text wrapping.
- Updated builds info link on the project settings page. (Ryan Harris)
- 27240 Make progress bars consistent.
- Only render hr when user can't archive project.
- 27352-search-label-filter-header.
- Include :author, :project, and :target in Event.with_associations.
- Don't instantiate AR objects in Event.in_projects.
- Don't capitalize environment name in show page.
- Update and pin the `jwt` gem to ~> 1.5.6.
- Edited the column header for the environments list from created to updated and added created to environments detail page colum header titles.
- Give ci status text on pipeline graph a better font-weight.
- Add default labels to bulk assign dropdowns.
- Only return target project's comments for a commit.
- Fixes Pipelines table is not showing branch name for commit.
- Fix regression where cmd-click stopped working for todos and merge request tabs.
- Fix stray pipelines API request when showing MR.
- Fix Merge request pipelines displays JSON.
- Fix current build arrow indicator.
- Fix contribution activity alignment.
- Show Pipeline(not Job) in MR desktop notification.
- Fix tooltips in mini pipeline graph.
- Display loading indicator when filtering ref switcher dropdown.
- Show pipeline graph in MR widget if there are any stages.
- Fix icon colors in merge request widget mini graph.
- Improve blockquote formatting in notification emails.
- Adds container to tooltip in order to make it work with overflow:hidden in parent element.
- Restore pagination to admin abuse reports.
- Ensure export files are removed after a namespace is deleted.
- Add `y` keyboard shortcut to move to file permalink.
- Adds /target_branch slash command functionality for merge requests. (YarNayar)
- Patch Asciidocs rendering to block XSS.
- contribution calendar scrolls from right to left.
- Copying a rendered issue/comment will paste into GFM textareas as actual GFM.
- Don't delete assigned MRs/issues when user is deleted.
- Remove new branch button for confidential issues.
- Don't allow project guests to subscribe to merge requests through the API. (Robert Schilling)
- Don't connect in Gitlab::Database.adapter_name.
- Prevent users from creating notes on resources they can't access.
- Ignore encrypted attributes in Import/Export.
- Change rspec test to guarantee window is resized before visiting page.
- Prevent users from deleting system deploy keys via the project deploy key API.
- Fix XSS vulnerability in SVG attachments.
- Make MR-review-discussions more reliable.
- fix incorrect sidekiq concurrency count in admin background page. (wendy0402)
- Make notification_service spec DRYer by making test reusable. (YarNayar)
- Redirect http://someproject.git to http://someproject. (blackst0ne)
- Fixed group label links in issue/merge request sidebar.
- Improve gl.utils.handleLocationHash tests.
- Fixed Issuable sidebar not closing on smaller/mobile sized screens.
- Resets assignee dropdown when sidebar is open.
- Disallow system notes for closed issuables.
- Fix timezone on issue boards due date.
- Remove unused js response from refs controller.
- Prevent the GitHub importer from assigning labels and comments to merge requests or issues belonging to other projects.
- Fixed merge requests tab extra margin when fixed to window.
- Patch XSS vulnerability in RDOC support.
- Refresh authorizations when transferring projects.
- Remove issue and MR counts from labels index.
- Don't use backup Active Record connections for Sidekiq.
- Add index to ci_trigger_requests for commit_id.
- Add indices to improve loading of labels page.
- Reduced query count for snippet search.
- Update GitLab Pages to v0.3.1.
- Upgrade omniauth gem to 1.3.2.
- Remove deprecated GitlabCiService.
- Requeue pending deletion projects.
## 8.16.6 (2017-02-17)
- API: Fix file downloading. !0 (8267)
......
......@@ -25,7 +25,7 @@
all = {
id: "all"
};
data = $.merge([all], groups[0], projects[0]);
data = [all].concat(groups[0], projects[0]);
return query.callback({
results: data
});
......
......@@ -141,7 +141,7 @@ module Elastic
{
query: {
bool: {
must: [{ term: { iid: iid } }]
filter: [{ term: { iid: iid } }]
}
}
}
......@@ -155,7 +155,8 @@ module Elastic
options[:public_and_internal_projects]
)
query_hash[:query][:bool][:filter] = {
query_hash[:query][:bool][:filter] ||= []
query_hash[:query][:bool][:filter] << {
has_parent: {
parent_type: "project",
query: {
......
......@@ -79,7 +79,7 @@ module Elastic
{ term: { confidential: false } }
end
query_hash[:query][:bool][:must] << filter
query_hash[:query][:bool][:filter] << filter
query_hash
end
end
......
......@@ -55,7 +55,7 @@ module Files
file_path = action[:file_path]
file_path = action[:previous_path] if action[:action] == :move
blob = repository.blob_at_branch(params[:branch_name], file_path)
blob = repository.blob_at_branch(params[:branch], file_path)
unless blob
raise_error("File to be #{action[:action]}d `#{file_path}` does not exist.")
......@@ -89,7 +89,7 @@ module Files
def validate_create(action)
return if project.empty_repo?
if repository.blob_at_branch(params[:branch_name], action[:file_path])
if repository.blob_at_branch(params[:branch], action[:file_path])
raise_error("Your changes could not be committed because a file with the name `#{action[:file_path]}` already exists.")
end
end
......@@ -102,14 +102,14 @@ module Files
raise_error("You must supply the original file path when moving file `#{action[:file_path]}`.")
end
blob = repository.blob_at_branch(params[:branch_name], action[:file_path])
blob = repository.blob_at_branch(params[:branch], action[:file_path])
if blob
raise_error("Move destination `#{action[:file_path]}` already exists.")
end
if action[:content].nil?
blob = repository.blob_at_branch(params[:branch_name], action[:previous_path])
blob = repository.blob_at_branch(params[:branch], action[:previous_path])
blob.load_all_data!(repository) if blob.truncated?
params[:actions][index][:content] = blob.data
end
......
---
title: Read-only "auditor" user role
merge_request: 998
author:
---
title: Also reset approvals on push when merge request is closed
merge_request: 1051
author:
---
title: 'Geo: Added `gitlab:geo:check` and improved `gitlab:envinfo` rake tasks'
merge_request: 1120
author:
---
title: Fix admin email notification recipient group select list
merge_request:
author:
---
title: Re-add removed params from projects and issues V3 API
merge_request: 1209
author:
---
title: Change Builds word to Pipelines in Mirror settings page
merge_request:
author:
---
title: Fix bundle tag in anaytics page
merge_request:
author:
---
title: 'Copy commit SHA to clipboard'
merge_request: 1066
---
title: 27240 Make progress bars consistent
title: "[Elasticsearch] More efficient search"
merge_request:
author:
---
title: Support v4 API for GitLab Geo endpoints
merge_request:
author:
---
title: Pull EE specific Gitlab::Auth code in to its own module
merge_request: 1112
author:
---
title: Add configurable minimum mirror sync time in admin section
merge_request: 1217
author:
---
title: Allow squashing merge requests into a single commit
merge_request:
author:
---
title: Rename Builds to Pipelines, CI/CD Pipelines, or Jobs everywhere
merge_request: 8787
author:
---
title: Don't require lib/gitlab/request_profiler/middleware.rb in config/initializers/request_profiler.rb
merge_request:
author:
---
title: Use reCaptcha when an issue is identified as a spam
merge_request: 8846
author:
---
title: Unify projects search by removing /projects/:search endpoint
merge_request: 8877
author:
---
title: Standardize branch name params as branch on V4 API
merge_request: 8936
author:
---
title: Allow creating protected branches when user can merge to such branch
merge_request: 8458
author:
---
title: Adds service trigger events to api
merge_request: 8324
author:
---
title: Create a TODO for user who set auto-merge when a build fails, merge conflict occurs
merge_request: 8056
author: twonegatives
---
title: Don't group issues by project on group-level and dashboard issue indexes.
merge_request: 8111
author: Bernardo Castro
---
title: Fix disable storing of sensitive information when importing a new repo
merge_request: 8885
author: Bernard Pietraga
---
title: Adds back ability to stop all environments
merge_request: 7379
author:
---
title: Force new password after password reset via API
merge_request:
author: George Andrinopoulos
---
title: Fix Ctrl+Click support for Todos and Merge Request page tabs
merge_request: 8898
author:
---
title: Refactor MergeRequests::BuildService
merge_request: 8462
author: Rydkin Maxim
---
title: 'Allows to search within project by commit hash'
merge_request:
author: YarNayar
---
title: Fix nested tasks in ordered list
merge_request: 8626
author:
---
title: Show organisation membership and delete comment on smaller viewports, plus change comment author name to username
merge_request:
author:
---
title: Prevent removal of input fields if it is the parent dropdown element
merge_request: 8397
author:
---
title: Remove flash warning from login page
merge_request: 8864
author: Gerald J. Padilla
---
title: Replace word user with member
merge_request: 8872
author:
---
title: Remove turbolinks.
merge_request: !8570
author:
---
title: Update pipeline and commit links when CI status is updated
merge_request: 8351
author:
---
title: Convert pipeline action icons to svg to have them propperly positioned
merge_request:
author:
---
title: Remove rogue scrollbars for issue comments with inline elements
merge_request:
author:
---
title: Align Segoe UI label text
merge_request:
author:
---
title: Don’t count tasks that are not defined as list items correctly
merge_request: 8526
author:
---
title: Add sorting pipeline for a commit
merge_request: 8319
author: Takuya Noguchi
---
title: Color + and - signs in diffs to increase code legibility
merge_request:
author:
---
title: Improve button accessibility on pipelines page
merge_request: 8561
author:
---
title: Fix tab index order on branch commits list page
merge_request:
author: Ryan Harris
---
title: Fix Sort by Recent Sign-in in Admin Area
merge_request: 8637
author: Poornima M
---
title: Add hover style to copy icon on commit page header
merge_request:
author: Ryan Harris
---
title: prevent diff unfolding link from appearing when there are no more lines to
show
merge_request: 8761
author:
---
title: Avoid repeated dashes in $CI_ENVIRONMENT_SLUG
merge_request: 8638
author:
---
title: Fixes hover cursor on pipeline pagenation
merge_request: 9003
author:
---
title: Add link verification to badge partial in order to render a badge without a link
merge_request: 8740
author:
---
title: Improve pipeline status icon linking in widgets
merge_request:
author:
---
title: Fix commit title bar and repository view copy clipboard button order on last commit in repository view
merge_request:
author:
---
title: Fix mini-pipeline stage tooltip text wrapping
merge_request:
author:
---
title: Prevent copying of line numbers in parallel diff view
merge_request: 8706
author:
---
title: Updated builds info link on the project settings page
merge_request:
author: Ryan Harris
---
title: fixed small mini pipeline graph line glitch
merge_request: 8804
author:
---
title: Unify MR diff file button style
merge_request: 8874
author:
---
title: Only render hr when user can't archive project.
merge_request: !8917
author:
---
title: Fix pipeline graph vertical spacing in Firefox and Safari
merge_request: 8886
author:
---
title: 27352-search-label-filter-header
merge_request:
author:
---
title: Include :author, :project, and :target in Event.with_associations
merge_request:
author:
---
title: Don't instantiate AR objects in Event.in_projects
merge_request:
author:
---
title: Don't capitalize environment name in show page
merge_request:
author:
---
title: Update and pin the `jwt` gem to ~> 1.5.6
merge_request:
author:
---
title: Edited the column header for the environments list from created to updated and added created to environments detail page colum header titles
merge_request:
author:
---
title: Fixes flickering of avatar border in mention dropdown
merge_request: 8950
author:
---
title: Fix MR widget url
merge_request: 8989
author:
---
title: Layer award emoji dropdown over the right sidebar
merge_request: 9004
author:
---
title: Update doc for enabling or disabling GitLab CI
merge_request: 8965
author: Takuya Noguchi
---
title: Give ci status text on pipeline graph a better font-weight
merge_request:
author:
---
title: Add default labels to bulk assign dropdowns
merge_request:
author:
---
title: Only return target project's comments for a commit
merge_request:
author:
---
title: Fixes Pipelines table is not showing branch name for commit
merge_request:
author:
---
title: Trigger autocomplete after selecting a slash command
merge_request: 9117
author:
---
title: Fix regression where cmd-click stopped working for todos and merge request
tabs
merge_request:
author:
---
title: Fix stray pipelines API request when showing MR
merge_request:
author:
---
title: Fix Merge request pipelines displays JSON
merge_request:
author:
---
title: Fix current build arrow indicator
merge_request:
author:
---
title: Fix contribution activity alignment
merge_request:
author:
---
title: Add space between text and loading icon in Megre Request Widget
merge_request: 9119
author:
---
title: Show Pipeline(not Job) in MR desktop notification
merge_request:
author:
---
title: Fix tooltips in mini pipeline graph
merge_request:
author:
---
title: Display loading indicator when filtering ref switcher dropdown
merge_request:
author:
---
title: Show pipeline graph in MR widget if there are any stages
merge_request:
author:
---
title: Fix icon colors in merge request widget mini graph
merge_request:
author:
---
title: Improve blockquote formatting in notification emails
merge_request:
author:
---
title: Adds container to tooltip in order to make it work with overflow:hidden in
parent element
merge_request:
author:
---
title: Restore pagination to admin abuse reports
merge_request:
author:
---
title: Present GitLab version for each V3 to V4 API change on v3_to_v4.md
merge_request:
author:
---
title: Fix notifications when set at group level
merge_request: 6813
author: Alexandre Maia
---
title: Ensure export files are removed after a namespace is deleted
merge_request:
author:
---
title: Add `y` keyboard shortcut to move to file permalink
merge_request:
author:
---
title: Remove deprecated MR and Issue endpoints and preserve V3 namespace
merge_request: 8967
author:
---
title: Adds /target_branch slash command functionality for merge requests
merge_request:
author: YarNayar
---
title: Add system hook for when a project is updated (other than rename/transfer)
merge_request: 5711
author: Tommy Beadle
---
title: 'API: Remove deprecated ''expires_at'' from project snippets'
merge_request: 8723
author: Robert Schilling
---
title: use babel to transpile all non-vendor javascript assets regardless of file
extension
merge_request: 8988
author:
---
title: Hide version check image if there is no internet connection
merge_request: 8355
author: Ken Ding
---
title: Increase process_commit queue weight from 2 to 3
merge_request: 9326
author: blackst0ne
---
title: 'Copy commit SHA to clipboard'
merge_request: 8547
---
title: contribution calendar scrolls from right to left
merge_request:
author:
---
title: Cop for gem fetched from a git source
merge_request: 8856
author: Adam Pahlevi
---
title: Copying a rendered issue/comment will paste into GFM textareas as actual GFM
merge_request:
author:
---
title: Disable automatic login after clicking email confirmation links
merge_request: 7472
author:
---
title: Display project ID in project settings
merge_request: 8572
author: winniehell
---
title: Adds documentation for how to use Vue.js
merge_request: 8866
author:
---
title: Replace static fixture for right_sidebar_spec.js
merge_request: 9211
author: winniehell
---
title: Add read-only full_path and full_name attributes to Group API
merge_request: 8827
author:
---
title: Change the reply shortcut to focus the field even without a selection.
merge_request: 8873
author: Brian Hall
---
title: Use vue.js Pipelines table in commit and merge request view
merge_request: 8844
author:
---
title: Use warning icon in mini-graph if stage passed conditionally
merge_request: 8503
author:
---
title: Remove new branch button for confidential issues
merge_request:
author:
---
title: Don't allow project guests to subscribe to merge requests through the API
merge_request:
author: Robert Schilling
---
title: Don't connect in Gitlab::Database.adapter_name
merge_request:
author:
---
title: Improve build policy and access abilities
merge_request: 8711
author:
---
title: Fix deleting projects with pipelines and builds
merge_request: 8960
author:
---
title: resolve deprecation warnings
merge_request: 8855
author: Adam Pahlevi
---
title: Preserve backward compatibility CI/CD and disallow setting `coverage` regexp in global context
merge_request: 8981
author:
---
title: Prevent users from creating notes on resources they can't access
merge_request:
author:
---
title: Ignore encrypted attributes in Import/Export
merge_request:
author:
---
title: Add ability to export project inherited group members to Import/Export
merge_request: 8923
author:
---
title: Fix job to pipeline renaming
merge_request: 9147
author:
---
title: Fix reply by email without sub-addressing for some clients from
Microsoft and Apple
merge_request: 8620
author:
---
title: Change rspec test to guarantee window is resized before visiting page
merge_request:
author:
---
title: Prevent users from deleting system deploy keys via the project deploy key API
merge_request:
author:
---
title: Make MR-review-discussions more reliable
merge_request:
author:
---
title: fix incorrect sidekiq concurrency count in admin background page
merge_request:
author: wendy0402
---
title: replace `find_with_namespace` with `find_by_full_path`
merge_request: 8949
author: Adam Pahlevi
---
title: Make notification_service spec DRYer by making test reusable
merge_request:
author: YarNayar
---
title: Redirect http://someproject.git to http://someproject
merge_request:
author: blackst0ne
---
title: use webpack to bundle frontend assets and use karma for frontend testing
merge_request: 7288
author:
---
title: Fixed group label links in issue/merge request sidebar
merge_request:
author:
---
title: Ensure autogenerated title does not cause failing spec
merge_request: 8963
author: brian m. carlson
---
title: Changed composer installer script in the CI PHP example doc
merge_request: 4342
author: Jeffrey Cafferata
---
title: Improve gl.utils.handleLocationHash tests
merge_request:
author:
---
title: Fixed Issuable sidebar not closing on smaller/mobile sized screens
merge_request:
author:
---
title: Add ability to define a coverage regex in the .gitlab-ci.yml
merge_request: 7447
author: Leandro Camargo
---
title: Resets assignee dropdown when sidebar is open
merge_request:
author:
---
title: Disallow system notes for closed issuables
merge_request:
author:
---
title: Fix timezone on issue boards due date
merge_request:
author:
---
title: Remove unused js response from refs controller
merge_request:
author:
---
title: Added GitLab Pages to CE
merge_request: 8463
author:
---
title: "Project labels can now be promoted to group labels"
merge_request: 7242
author: Olaf Tomalka
---
title: Support unauthenticated LFS object downloads for public projects
merge_request: 8824
author: Ben Boeckel
---
title: PlantUML support for Markdown
merge_request: 8588
author: Horacio Sanson
---
title: Replace static fixture for merge_request_tabs_spec.js
merge_request: 9172
author: winniehell
---
title: adds avatar for discussion note
merge_request: 8734
author:
---
title: Fixed merge requests tab extra margin when fixed to window
merge_request:
author:
---
title: Flag multiple empty lines in eslint, fix offenses.
merge_request: 8137
author:
---
title: dismiss sidebar on repo buttons click
merge_request: 8798
author: Adam Pahlevi
---
title: Support notes when a project is not specified (personal snippet notes)
merge_request: 8468
author:
---
title: Make all system notes lowercase
merge_request: 8807
author:
---
title: Redesign searchbar in admin project list
merge_request: 8776
author:
---
title: 'Search feature: redirects to commit page if query is commit sha and only commit
found'
merge_request: 8028
author: YarNayar
---
title: allow relative url change without recompiling frontend assets
merge_request: 8831
author:
---
title: 'API: Remove /projects/:id/keys/.. endpoints'
merge_request: 8716
author: Robert Schilling
---
title: Remove issue and MR counts from labels index
merge_request:
author:
---
title: Add 'View on [env]' link to blobs and individual files in diffs
merge_request: 8867
author:
---
title: Don't perform Devise trackable updates on blocked User records
merge_request: 8915
author:
---
title: Add index to ci_trigger_requests for commit_id
merge_request:
author:
---
title: Add indices to improve loading of labels page
merge_request:
author:
---
title: Fixed "substract" typo on /help/user/project/slash_commands
merge_request: 8976
author: Jason Aquino
---
title: Display fullscreen button on small screens
merge_request: 5302
author: winniehell
---
title: Reduced query count for snippet search
merge_request:
author:
---
title: Only show Merge Request button when user can create a MR
merge_request: 8639
author:
---
title: Introduce maximum session time for terminal websocket connection
merge_request: 8413
author:
---
title: Update GitLab Pages to v0.3.1
merge_request:
author:
---
title: upgrade babel 5.8.x to babel 6.22.x
merge_request: 9072
author:
---
title: Upgrade omniauth gem to 1.3.2
merge_request:
author:
---
title: upgrade to webpack v2.2
merge_request: 9078
author:
---
title: Mark MR as WIP when pushing WIP commits
merge_request: 8124
author: Jurre Stender @jurre
---
title: Remove hover animation from row elements
title: Chat slash commands show labels correctly
merge_request:
author:
---
title: Reformat messages ChatOps
merge_request: 8528
author:
---
title: Remove deprecated GitlabCiService
merge_request:
author:
---
title: Requeue pending deletion projects
merge_request:
author:
......@@ -102,6 +102,8 @@ The Pages daemon doesn't listen to the outside world.
1. [Reconfigure GitLab][reconfigure]
Watch the [video tutorial][video-admin] for this configuration.
### Wildcard domains with TLS support
>**Requirements:**
......@@ -270,3 +272,4 @@ latest previous version.
[reconfigure]: ../restart_gitlab.md#omnibus-gitlab-reconfigure
[restart]: ../restart_gitlab.md#installations-from-source
[gitlab-pages]: https://gitlab.com/gitlab-org/gitlab-pages/tree/v0.2.4
[video-admin]: https://youtu.be/dD8c7WNcc6s
......@@ -193,11 +193,11 @@ POST /projects/:id/repository/branches
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
| `branch_name` | string | yes | The name of the branch |
| `branch` | string | yes | The name of the branch |
| `ref` | string | yes | The branch name or commit SHA to create branch from |
```bash
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/5/repository/branches?branch_name=newbranch&ref=master"
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/5/repository/branches?branch=newbranch&ref=master"
```
Example response:
......
......@@ -69,7 +69,7 @@ POST /projects/:id/repository/commits
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of a project or NAMESPACE/PROJECT_NAME |
| `branch_name` | string | yes | The name of a branch |
| `branch` | string | yes | The name of a branch |
| `commit_message` | string | yes | Commit message |
| `actions[]` | array | yes | An array of action hashes to commit as a batch. See the next table for what attributes it can take. |
| `author_email` | string | no | Specify the commit author's email address |
......@@ -87,7 +87,7 @@ POST /projects/:id/repository/commits
```bash
PAYLOAD=$(cat << 'JSON'
{
"branch_name": "master",
"branch": "master",
"commit_message": "some commit message",
"actions": [
{
......
......@@ -46,22 +46,22 @@ POST /projects/:id/repository/files
```
```bash
curl --request POST --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch_name=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20content&commit_message=create%20a%20new%20file'
curl --request POST --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20content&commit_message=create%20a%20new%20file'
```
Example response:
```json
{
"file_path": "app/project.rb",
"branch_name": "master"
"file_name": "app/project.rb",
"branch": "master"
}
```
Parameters:
- `file_path` (required) - Full path to new file. Ex. lib/class.rb
- `branch_name` (required) - The name of branch
- `branch` (required) - The name of branch
- `encoding` (optional) - Change encoding to 'base64'. Default is text.
- `author_email` (optional) - Specify the commit author's email address
- `author_name` (optional) - Specify the commit author's name
......@@ -75,22 +75,22 @@ PUT /projects/:id/repository/files
```
```bash
curl --request PUT --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch_name=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20other%20content&commit_message=update%20file'
curl --request PUT --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&content=some%20other%20content&commit_message=update%20file'
```
Example response:
```json
{
"file_path": "app/project.rb",
"branch_name": "master"
"file_name": "app/project.rb",
"branch": "master"
}
```
Parameters:
- `file_path` (required) - Full path to file. Ex. lib/class.rb
- `branch_name` (required) - The name of branch
- `branch` (required) - The name of branch
- `encoding` (optional) - Change encoding to 'base64'. Default is text.
- `author_email` (optional) - Specify the commit author's email address
- `author_name` (optional) - Specify the commit author's name
......@@ -113,22 +113,22 @@ DELETE /projects/:id/repository/files
```
```bash
curl --request DELETE --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch_name=master&author_email=author%40example.com&author_name=Firstname%20Lastname&commit_message=delete%20file'
curl --request DELETE --header 'PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK' 'https://gitlab.example.com/api/v3/projects/13083/repository/files?file_path=app/project.rb&branch=master&author_email=author%40example.com&author_name=Firstname%20Lastname&commit_message=delete%20file'
```
Example response:
```json
{
"file_path": "app/project.rb",
"branch_name": "master"
"file_name": "app/project.rb",
"branch": "master"
}
```
Parameters:
- `file_path` (required) - Full path to file. Ex. lib/class.rb
- `branch_name` (required) - The name of branch
- `branch` (required) - The name of branch
- `author_email` (optional) - Specify the commit author's email address
- `author_name` (optional) - Specify the commit author's name
- `commit_message` (required) - Commit message
......@@ -4,17 +4,20 @@ Our V4 API version is currently available as *Beta*! It means that V3
will still be supported and remain unchanged for now, but be aware that the following
changes are in V4:
### Changes
### 8.17
- Removed `/projects/:search` (use: `/projects?search=x`)
- `iid` filter has been removed from `projects/:id/issues`
- `projects/:id/merge_requests?iid[]=x&iid[]=y` array filter has been renamed to `iids`
- Endpoints under `projects/merge_request/:id` have been removed (use: `projects/merge_requests/:id`)
- Project snippets do not return deprecated field `expires_at`
- Endpoints under `projects/:id/keys` have been removed (use `projects/:id/deploy_keys`)
- Status 409 returned for POST `project/:id/members` when a member already exists
- Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar`
- Removed the following deprecated Templates endpoints (these are still accessible with `/templates` prefix)
- Removed `/projects/:search` (use: `/projects?search=x`) [!8877](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8877)
- `iid` filter has been removed from `projects/:id/issues` [!8967](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8967)
- `projects/:id/merge_requests?iid[]=x&iid[]=y` array filter has been renamed to `iids` [!8793](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8793)
- Endpoints under `projects/merge_request/:id` have been removed (use: `projects/merge_requests/:id`) [!8793](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8793)
- Project snippets do not return deprecated field `expires_at` [!8723](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8723)
- Endpoints under `projects/:id/keys` have been removed (use `projects/:id/deploy_keys`) [!8716](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8716)
### 9.0
- Status 409 returned for POST `project/:id/members` when a member already exists [!9093](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9093)
- Moved `DELETE /projects/:id/star` to `POST /projects/:id/unstar` [!9328](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9328)
- Removed the following deprecated Templates endpoints (these are still accessible with `/templates` prefix) [!8853](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8853)
- `/licences`
- `/licences/:key`
- `/gitignores`
......@@ -23,11 +26,17 @@ changes are in V4:
- `/gitignores/:key`
- `/gitlab_ci_ymls/:key`
- `/dockerfiles/:key`
- Moved `/projects/fork/:id` to `/projects/:id/fork`
- Endpoints `/projects/owned`, `/projects/visible`, `/projects/starred` & `/projects/all` are consolidated into `/projects` using query parameters
- Return pagination headers for all endpoints that return an array
- Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead
- Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)`
- Make subscription API more RESTful. Use `post ":id/#{type}/:subscribable_id/subscribe"` to subscribe and `post ":id/#{type}/:subscribable_id/unsubscribe"` to unsubscribe from a resource.
- Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR)
- Moved `/projects/fork/:id` to `/projects/:id/fork` [!8940](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8940)
- Endpoints `/projects/owned`, `/projects/visible`, `/projects/starred` & `/projects/all` are consolidated into `/projects` using query parameters [!8962](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8962)
- Return pagination headers for all endpoints that return an array [!8606](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8606)
- Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead [!9366](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9366)
- Moved `PUT /users/:id/(block|unblock)` to `POST /users/:id/(block|unblock)` [!9371](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9371)
- Make subscription API more RESTful. Use `post ":project_id/:subscribable_type/:subscribable_id/subscribe"` to subscribe and `post ":project_id/:subscribable_type/:subscribable_id/unsubscribe"` to unsubscribe from a resource. [!9325](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9325)
- Labels filter on `projects/:id/issues` and `/issues` now matches only issues containing all labels (i.e.: Logical AND, not OR) [!8849](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8849)
- Renamed param `branch_name` to `branch` on the following endpoints [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936)
- POST `:id/repository/branches`
- POST `:id/repository/commits`
- POST/PUT/DELETE `:id/repository/files`
- Renamed `branch_name` to `branch` on DELETE `id/repository/branches/:branch` response [!8936](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8936)
- Remove `public` param from create and edit actions of projects [!8736](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8736)
- Notes do not return deprecated field `upvote` and `downvote` [!1275](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/1275)
# GitLab Pages from A to Z: Part 1
- **Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates**
- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_
- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_
----
This is a comprehensive guide, made for those who want to
publish a website with GitLab Pages but aren't familiar with
the entire process involved.
To **enable** GitLab Pages for GitLab CE (Community Edition)
and GitLab EE (Enterprise Edition), please read the
[admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html),
and/or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s).
>**Note:**
For this guide, we assume you already have GitLab Pages
server up and running for your GitLab instance.
## What you need to know before getting started
Before we begin, let's understand a few concepts first.
### Static sites
GitLab Pages only supports static websites, meaning,
your output files must be HTML, CSS, and JavaScript only.
To create your static site, you can either hardcode in HTML,
CSS, and JS, or use a [Static Site Generator (SSG)](https://www.staticgen.com/)
to simplify your code and build the static site for you,
which is highly recommendable and much faster than hardcoding.
---
- Read through this technical overview on [Static versus Dynamic Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/)
- Understand [how modern Static Site Generators work](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) and what you can add to your static site
- You can use [any SSG with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
- Fork an [example project](https://gitlab.com/pages) to build your website based upon
### GitLab Pages domain
If you set up a GitLab Pages project on GitLab.com,
it will automatically be accessible under a
[subdomain of `namespace.pages.io`](https://docs.gitlab.com/ce/user/project/pages/).
The `namespace` is defined by your username on GitLab.com,
or the group name you created this project under.
>**Note:**
If you use your own GitLab instance to deploy your
site with GitLab Pages, check with your sysadmin what's your
Pages wildcard domain. This guide is valid for any GitLab instance,
you just need to replace Pages wildcard domain on GitLab.com
(`*.gitlab.io`) with your own.
#### Practical examples
**Project Websites:**
- You created a project called `blog` under your username `john`,
therefore your project URL is `https://gitlab.com/john/blog/`.
Once you enable GitLab Pages for this project, and build your site,
it will be available under `https://john.gitlab.io/blog/`.
- You created a group for all your websites called `websites`,
and a project within this group is called `blog`. Your project
URL is `https://gitlab.com/websites/blog/`. Once you enable
GitLab Pages for this project, the site will live under
`https://websites.gitlab.io/blog/`.
**User and Group Websites:**
- Under your username, `john`, you created a project called
`john.gitlab.io`. Your project URL will be `https://gitlab.com/john/john.gitlab.io`.
Once you enable GitLab Pages for your project, your website
will be published under `https://john.gitlab.io`.
- Under your group `websites`, you created a project called
`websites.gitlab.io`. your project's URL will be `https://gitlab.com/websites/websites.gitlab.io`. Once you enable GitLab Pages for your project,
your website will be published under `https://websites.gitlab.io`.
**General example:**
- On GitLab.com, a project site will always be available under
`https://namespace.gitlab.io/project-name`
- On GitLab.com, a user or group website will be available under
`https://namespace.gitlab.io/`
- On your GitLab instance, replace `gitlab.io` above with your
Pages server domain. Ask your sysadmin for this information.
### DNS Records
A Domain Name System (DNS) web service routes visitors to websites
by translating domain names (such as `www.example.com`) into the
numeric IP addresses (such as `192.0.2.1`) that computers use to
connect to each other.
A DNS record is created to point a (sub)domain to a certain location,
which can be an IP address or another domain. In case you want to use
GitLab Pages with your own (sub)domain, you need to access your domain's
registrar control panel to add a DNS record pointing it back to your
GitLab Pages site.
Note that **how to** add DNS records depends on which server your domain
is hosted on. Every control panel has its own place to do it. If you are
not an admin of your domain, and don't have access to your registrar,
you'll need to ask for the technical support of your hosting service
to do it for you.
To help you out, we've gathered some instructions on how to do that
for the most popular hosting services:
- [Amazon](http://docs.aws.amazon.com/gettingstarted/latest/swh/getting-started-configure-route53.html)
- [Bluehost](https://my.bluehost.com/cgi/help/559)
- [CloudFlare](https://support.cloudflare.com/hc/en-us/articles/200169096-How-do-I-add-A-records-)
- [cPanel](https://documentation.cpanel.net/display/ALD/Edit+DNS+Zone)
- [DreamHost](https://help.dreamhost.com/hc/en-us/articles/215414867-How-do-I-add-custom-DNS-records-)
- [Go Daddy](https://www.godaddy.com/help/add-an-a-record-19238)
- [Hostgator](http://support.hostgator.com/articles/changing-dns-records)
- [Inmotion hosting](https://my.bluehost.com/cgi/help/559)
- [Media Temple](https://mediatemple.net/community/products/dv/204403794/how-can-i-change-the-dns-records-for-my-domain)
- [Microsoft](https://msdn.microsoft.com/en-us/library/bb727018.aspx)
If your hosting service is not listed above, you can just try to
search the web for "how to add dns record on <my hosting service>".
#### DNS A record
In case you want to point a root domain (`example.com`) to your
GitLab Pages site, deployed to `namespace.gitlab.io`, you need to
log into your domain's admin control panel and add a DNS `A` record
pointing your domain to Pages' server IP address. For projects on
GitLab.com, this IP is `104.208.235.32`. For projects leaving in
other GitLab instances (CE or EE), please contact your sysadmin
asking for this information (which IP address is Pages server
running on your instance).
**Practical Example:**
![DNS A record pointing to GitLab.com Pages server](img/dns_a_record_example.png)
#### DNS CNAME record
In case you want to point a subdomain (`hello-world.example.com`)
to your GitLab Pages site initially deployed to `namespace.gitlab.io`,
you need to log into your domain's admin control panel and add a DNS
`CNAME` record pointing your subdomain to your website URL
(`namespace.gitlab.io`) address.
Notice that, despite it's a user or project website, the `CNAME`
should point to your Pages domain (`namespace.gitlab.io`),
without any `/project-name`.
**Practical Example:**
![DNS CNAME record pointing to GitLab.com project](img/dns_cname_record_example.png)
#### TL;DR
| From | DNS Record | To |
| ---- | ---------- | -- |
| domain.com | A | 104.208.235.32 |
| subdomain.domain.com | CNAME | namespace.gitlab.io |
> **Notes**:
>
> - **Do not** use a CNAME record if you want to point your
`domain.com` to your GitLab Pages site. Use an `A` record instead.
> - **Do not** add any special chars after the default Pages
domain. E.g., **do not** point your `subdomain.domain.com` to
`namespace.gitlab.io.` or `namespace.gitlab.io/`.
### SSL/TLS Certificates
Every GitLab Pages project on GitLab.com will be available under
HTTPS for the default Pages domain (`*.gitlab.io`). Once you set
up your Pages project with your custom (sub)domain, if you want
it secured by HTTPS, you will have to issue a certificate for that
(sub)domain and install it on your project.
>**Note:**
Certificates are NOT required to add to your custom
(sub)domain on your GitLab Pages project, though they are
highly recommendable.
The importance of having any website securely served under HTTPS
is explained on the introductory section of the blog post
[Secure GitLab Pages with StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/#https-a-quick-overview).
The reason why certificates are so important is that they encrypt
the connection between the **client** (you, me, your visitors)
and the **server** (where you site lives), through a keychain of
authentications and validations.
### Issuing Certificates
GitLab Pages accepts [PEM](https://support.quovadisglobal.com/kb/a37/what-is-pem-format.aspx) certificates issued by
[Certificate Authorities (CA)](https://en.wikipedia.org/wiki/Certificate_authority)
and self-signed certificates. Of course,
[you'd rather issue a certificate than generate a self-signed](https://en.wikipedia.org/wiki/Self-signed_certificate),
for security reasons and for having browsers trusting your
site's certificate.
There are several different kinds of certificates, each one
with certain security level. A static personal website will
not require the same security level as an online banking web app,
for instance. There are a couple Certificate Authorities that
offer free certificates, aiming to make the internet more secure
to everyone. The most popular is [Let's Encrypt](https://letsencrypt.org/),
which issues certificates trusted by most of browsers, it's open
source, and free to use. Please read through this tutorial to
understand [how to secure your GitLab Pages website with Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/).
With the same popularity, there are [certificates issued by CloudFlare](https://www.cloudflare.com/ssl/),
which also offers a [free CDN service](https://blog.cloudflare.com/cloudflares-free-cdn-and-you/).
Their certs are valid up to 15 years. Read through the tutorial on
[how to add a CloudFlare Certificate to your GitLab Pages website](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/).
### Adding certificates to your project
Regardless the CA you choose, the steps to add your certificate to
your Pages project are the same.
#### What do you need
1. A PEM certificate
1. An intermediate certificate
1. A public key
![Pages project - adding certificates](img/add_certificate_to_pages.png)
These fields are found under your **Project**'s **Settings** > **Pages** > **New Domain**.
#### What's what?
- A PEM certificate is the certificate generated by the CA,
which needs to be added to the field **Certificate (PEM)**.
- An [intermediate certificate](https://en.wikipedia.org/wiki/Intermediate_certificate_authority) (aka "root certificate") is
the part of the encryption keychain that identifies the CA.
Usually it's combined with the PEM certificate, but there are
some cases in which you need to add them manually.
[CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/)
are one of these cases.
- A public key is an encrypted key which validates
your PEM against your domain.
#### Now what?
Now that you hopefully understand why you need all
of this, it's simple:
- Your PEM certificate needs to be added to the first field
- If your certificate is missing its intermediate, copy
and paste the root certificate (usually available from your CA website)
and paste it in the [same field as your PEM certificate](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/),
just jumping a line between them.
- Copy your public key and paste it in the last field
>**Note:**
**Do not** open certificates or encryption keys in
regular text editors. Always use code editors (such as
Sublime Text, Atom, Dreamweaver, Brackets, etc).
|||
|:--|--:|
||[**Part 2: Quick start guide - Setting up GitLab Pages →**](getting_started_part_two.md)|
# GitLab Pages from A to Z: Part 3
- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_
- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_
- **Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages**
---
## Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages
[GitLab CI](https://about.gitlab.com/gitlab-ci/) serves
numerous purposes, to build, test, and deploy your app
from GitLab through
[Continuous Integration, Continuous Delivery, and Continuous Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/)
methods. You will need it to build your website with GitLab Pages,
and deploy it to the Pages server.
What this file actually does is telling the
[GitLab Runner](https://docs.gitlab.com/runner/) to run scripts
as you would do from the command line. The Runner acts as your
terminal. GitLab CI tells the Runner which commands to run.
Both are built-in in GitLab, and you don't need to set up
anything for them to work.
Explaining [every detail of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html)
and GitLab Runner is out of the scope of this guide, but we'll
need to understand just a few things to be able to write our own
`.gitlab-ci.yml` or tweak an existing one. It's an
[Yaml](http://docs.ansible.com/ansible/YAMLSyntax.html) file,
with its own syntax. You can always check your CI syntax with
the [GitLab CI Lint Tool](https://gitlab.com/ci/lint).
**Practical Example:**
Let's consider you have a [Jekyll](https://jekyllrb.com/) site.
To build it locally, you would open your terminal, and run `jekyll build`.
Of course, before building it, you had to install Jekyll in your computer.
For that, you had to open your terminal and run `gem install jekyll`.
Right? GitLab CI + GitLab Runner do the same thing. But you need to
write in the `.gitlab-ci.yml` the script you want to run so
GitLab Runner will do it for you. It looks more complicated then it
is. What you need to tell the Runner:
```
$ gem install jekyll
$ jekyll build
```
### Script
To transpose this script to Yaml, it would be like this:
```yaml
script:
- gem install jekyll
- jekyll build
```
### Job
So far so good. Now, each `script`, in GitLab is organized by
a `job`, which is a bunch of scripts and settings you want to
apply to that specific task.
```yaml
job:
script:
- gem install jekyll
- jekyll build
```
For GitLab Pages, this `job` has a specific name, called `pages`,
which tells the Runner you want that task to deploy your website
with GitLab Pages:
```yaml
pages:
script:
- gem install jekyll
- jekyll build
```
### The `public` directory
We also need to tell Jekyll where do you want the website to build,
and GitLab Pages will only consider files in a directory called `public`.
To do that with Jekyll, we need to add a flag specifying the
[destination (`-d`)](https://jekyllrb.com/docs/usage/) of the
built website: `jekyll build -d public`. Of course, we need
to tell this to our Runner:
```yaml
pages:
script:
- gem install jekyll
- jekyll build -d public
```
### Artifacts
We also need to tell the Runner that this _job_ generates
_artifacts_, which is the site built by Jekyll.
Where are these artifacts stored? In the `public` directory:
```yaml
pages:
script:
- gem install jekyll
- jekyll build -d public
artifacts:
paths:
- public
```
The script above would be enough to build your Jekyll
site with GitLab Pages. But, from Jekyll 3.4.0 on, its default
template originated by `jekyll new project` requires
[Bundler](http://bundler.io/) to install Jekyll dependencies
and the default theme. To adjust our script to meet these new
requirements, we only need to install and build Jekyll with Bundler:
```yaml
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
```
That's it! A `.gitlab-ci.yml` with the content above would deploy
your Jekyll 3.4.0 site with GitLab Pages. This is the minimum
configuration for our example. On the steps below, we'll refine
the script by adding extra options to our GitLab CI.
### Image
At this point, you probably ask yourself: "okay, but to install Jekyll
I need Ruby. Where is Ruby on that script?". The answer is simple: the
first thing GitLab Runner will look for in your `.gitlab-ci.yml` is a
[Docker](https://www.docker.com/) image specifying what do you need in
your container to run that script:
```yaml
image: ruby:2.3
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
```
In this case, you're telling the Runner to pull this image, which
contains Ruby 2.3 as part of its file system. When you don't specify
this image in your configuration, the Runner will use a default
image, which is Ruby 2.1.
If your SSG needs [NodeJS](https://nodejs.org/) to build, you'll
need to specify which image you want to use, and this image should
contain NodeJS as part of its file system. E.g., for a
[Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:4.2.2`.
>**Note:**
We're not trying to explain what a Docker image is,
we just need to introduce the concept with a minimum viable
explanation. To know more about Docker images, please visit
their website or take a look at a
[summarized explanation](http://paislee.io/how-to-automate-docker-deployments/) here.
Let's go a little further.
### Branching
If you use GitLab as a version control platform, you will have your
branching strategy to work on your project. Meaning, you will have
other branches in your project, but you'll want only pushes to the
default branch (usually `master`) to be deployed to your website.
To do that, we need to add another line to our CI, telling the Runner
to only perform that _job_ called `pages` on the `master` branch `only`:
```yaml
image: ruby:2.3
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
```
### Stages
Another interesting concept to keep in mind are build stages.
Your web app can pass through a lot of tests and other tasks
until it's deployed to staging or production environments.
There are three default stages on GitLab CI: build, test,
and deploy. To specify which stage your _job_ is running,
simply add another line to your CI:
```yaml
image: ruby:2.3
pages:
stage: deploy
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
```
You might ask yourself: "why should I bother with stages
at all?" Well, let's say you want to be able to test your
script and check the built site before deploying your site
to production. You want to run the test exactly as your
script will do when you push to `master`. It's simple,
let's add another task (_job_) to our CI, telling it to
test every push to other branches, `except` the `master` branch:
```yaml
image: ruby:2.3
pages:
stage: deploy
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle install
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
The `test` job is running on the stage `test`, Jekyll
will build the site in a directory called `test`, and
this job will affect all the branches except `master`.
The best benefit of applying _stages_ to different
_jobs_ is that every job in the same stage builds in
parallel. So, if your web app needs more than one test
before being deployed, you can run all your test at the
same time, it's not necessary to wait one test to finish
to run the other. Of course, this is just a brief
introduction of GitLab CI and GitLab Runner, which are
tools much more powerful than that. This is what you
need to be able to create and tweak your builds for
your GitLab Pages site.
### Before Script
To avoid running the same script multiple times across
your _jobs_, you can add the parameter `before_script`,
in which you specify which commands you want to run for
every single _job_. In our example, notice that we run
`bundle install` for both jobs, `pages` and `test`.
We don't need to repeat it:
```yaml
image: ruby:2.3
before_script:
- bundle install
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
### Caching Dependencies
If you want to cache the installation files for your
projects dependencies, for building faster, you can
use the parameter `cache`. For this example, we'll
cache Jekyll dependencies in a `vendor` directory
when we run `bundle install`:
```yaml
image: ruby:2.3
cache:
paths:
- vendor/
before_script:
- bundle install --path vendor
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
For this specific case, we need to exclude `/vendor`
from Jekyll `_config.yml` file, otherwise Jekyll will
understand it as a regular directory to build
together with the site:
```yml
exclude:
- vendor
```
There we go! Now our GitLab CI not only builds our website,
but also **continuously test** pushes to feature-branches,
**caches** dependencies installed with Bundler, and
**continuously deploy** every push to the `master` branch.
## Advanced GitLab CI for GitLab Pages
What you can do with GitLab CI is pretty much up to your
creativity. Once you get used to it, you start creating
awesome scripts that automate most of tasks you'd do
manually in the past. Read through the
[documentation of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html)
to understand how to go even further on your scripts.
- On this blog post, understand the concept of
[using GitLab CI `environments` to deploy your
web app to staging and production](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/).
- On this post, learn [how to run jobs sequentially,
in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/)
- On this blog post, we go through the process of
[pulling specific directories from different projects](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
to deploy this website you're looking at, docs.gitlab.com.
- On this blog post, we teach you [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/).
|||
|:--|--:|
|[**← Part 2: Quick start guide - Setting up GitLab Pages**](getting_started_part_two.md)||
# GitLab Pages from A to Z: Part 2
> Type: user guide
>
> Level: beginner
- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_
- **Part 2: Quick Start Guide - Setting Up GitLab Pages**
- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_
----
## Setting up GitLab Pages
For a complete step-by-step tutorial, please read the
blog post [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). The following sections will explain
what do you need and why do you need them.
## What you need to get started
1. A project
1. A configuration file (`.gitlab-ci.yml`) to deploy your site
1. A specific `job` called `pages` in the configuration file
that will make GitLab aware that you are deploying a GitLab Pages website
Optional Features:
1. A custom domain or subdomain
1. A DNS pointing your (sub)domain to your Pages site
1. **Optional**: an SSL/TLS certificate so your custom
domain is accessible under HTTPS.
## Project
Your GitLab Pages project is a regular project created the
same way you do for the other ones. To get started with GitLab Pages, you have two ways:
- Fork one of the templates from Page Examples, or
- Create a new project from scratch
Let's go over both options.
### Fork a project to get started from
To make things easy for you, we've created this
[group](https://gitlab.com/pages) of default projects
containing the most popular SSGs templates.
Watch the [video tutorial](https://youtu.be/TWqh9MtT4Bg) we've
created for the steps below.
1. Choose your SSG template
1. Fork a project from the [Pages group](https://gitlab.com/pages)
1. Remove the fork relationship by navigating to your **Project**'s **Settings** > **Edit Project**
![remove fork relashionship](img/remove_fork_relashionship.png)
1. Enable Shared Runners for your fork: navigate to your **Project**'s **Settings** > **CI/CD Pipelines**
1. Trigger a build (push a change to any file)
1. As soon as the build passes, your website will have been deployed with GitLab Pages. Your website URL will be available under your **Project**'s **Settings** > **Pages**
To turn a **project website** forked from the Pages group into a **user/group** website, you'll need to:
- Rename it to `namespace.gitlab.io`: navigate to **Project**'s **Settings** > **Edit Project** > **Rename repository**
- Adjust your SSG's [base URL](#urls-and-baseurls) to from `"project-name"` to `""`. This setting will be at a different place for each SSG, as each of them have their own structure and file tree. Most likelly, it will be in the SSG's config file.
> **Notes:**
>
>1. Why do I need to remove the fork relationship?
>
> Unless you want to contribute to the original project,
you won't need it connected to the upstream. A
[fork](https://about.gitlab.com/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/#fork)
is useful for submitting merge requests to the upstream.
>
> 2. Why do I need to enable Shared Runners?
>
> Shared Runners will run the script set by your GitLab CI
configuration file. They're enabled by default to new projects,
but not to forks.
### Create a project from scratch
1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**,
click **New project**, and name it considering the
[practical examples](getting_started_part_one.md#practical-examples).
1. Clone it to your local computer, add your website
files to your project, add, commit and push to GitLab.
1. From the your **Project**'s page, click **Set up CI**:
![setup GitLab CI](img/setup_ci.png)
1. Choose one of the templates from the dropbox menu.
Pick up the template corresponding to the SSG you're using (or plain HTML).
![gitlab-ci templates](img/choose_ci_template.png)
Once you have both site files and `.gitlab-ci.yml` in your project's
root, GitLab CI will build your site and deploy it with Pages.
Once the first build passes, you see your site is live by
navigating to your **Project**'s **Settings** > **Pages**,
where you'll find its default URL.
> **Notes:**
>
> - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but,
if you don't find yours among the templates, you'll need
to configure your own `.gitlab-ci.yml`. Do do that, please
read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md). New SSGs are very welcome among
the [example projects](https://gitlab.com/pages). If you set
up a new one, please
[contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md)
to our examples.
>
> - The second step _"Clone it to your local computer"_, can be done
differently, achieving the same results: instead of cloning the bare
repository to you local computer and moving your site files into it,
you can run `git init` in your local website directory, add the
remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`,
then add, commit, and push.
### URLs and Baseurls
Every Static Site Generator (SSG) default configuration expects
to find your website under a (sub)domain (`example.com`), not
in a subdirectory of that domain (`example.com/subdir`). Therefore,
whenever you publish a project website (`namespace.gitlab.io/project-name`),
you'll have to look for this configuration (base URL) on your SSG's
documentation and set it up to reflect this pattern.
For example, for a Jekyll site, the `baseurl` is defined in the Jekyll
configuration file, `_config.yml`. If your website URL is
`https://john.gitlab.io/blog/`, you need to add this line to `_config.yml`:
```yaml
baseurl: "/blog"
```
On the contrary, if you deploy your website after forking one of
our [default examples](https://gitlab.com/pages), the baseurl will
already be configured this way, as all examples there are project
websites. If you decide to make yours a user or group website, you'll
have to remove this configuration from your project. For the Jekyll
example we've just mentioned, you'd have to change Jekyll's `_config.yml` to:
```yaml
baseurl: ""
```
|||
|:--|--:|
|[**← Part 1: Static sites, domains, DNS records, and SSL/TLS certificates**](getting_started_part_one.md)|[**Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages →**](getting_started_part_three.md)|
# All you need to know about GitLab Pages
With GitLab Pages you can create static websites for your GitLab projects,
groups, or user accounts. You can use any static website generator: Jekyll,
Middleman, Hexo, Hugo, Pelican, you name it! Connect as many customs domains
as you like and bring your own TLS certificate to secure them.
Here's some info we have gathered to get you started.
## General info
- [Product webpage](https://pages.gitlab.io)
- [We're bringing GitLab Pages to CE](https://about.gitlab.com/2016/12/24/were-bringing-gitlab-pages-to-community-edition/)
- [Pages group - templates](https://gitlab.com/pages)
## Getting started
- GitLab Pages from A to Z
- [Part 1: Static sites, domains, DNS records, and SSL/TLS certificates](getting_started_part_one.md)
- [Part 2: Quick start guide - Setting up GitLab Pages](getting_started_part_two.md)
- [Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)
- [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) a comprehensive step-by-step guide
- Secure GitLab Pages custom domain with SSL/TLS certificates
- [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/)
- [CloudFlare](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/)
- [StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/)
- Static Site Generators - Blog posts series
- [SSGs part 1: Static vs dynamic websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/)
- [SSGs part 2: Modern static site generators](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/)
- [SSGs part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
- [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/)
## Video tutorials
- [How to publish a website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg)
- [How to Enable GitLab Pages for GitLab CE and EE](https://youtu.be/dD8c7WNcc6s)
## Advanced use
- Blog Posts:
- [GitLab CI: Run jobs sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/)
- [GitLab CI: Deployment & environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/)
- [Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
- [Publish code coverage reports with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/)
## Specific documentation
- [User docs](../user/project/pages/index.md)
- [Admin docs](../administration/pages/index.md)
......@@ -14,6 +14,8 @@ deploy static pages for your individual projects, your user or your group.
Read [GitLab Pages on GitLab.com](#gitlab-pages-on-gitlab-com) for specific
information, if you are using GitLab.com to host your website.
Read through [All you Need to Know About GitLab Pages][pages-index-guide] for a list of all learning materials we have prepared for GitLab Pages (webpages, articles, guides, blog posts, video tutorials).
## Getting started with GitLab Pages
> **Note:**
......@@ -96,6 +98,13 @@ The steps to create a project page for a user or a group are identical:
A user's project will be served under `http(s)://username.example.io/projectname`
whereas a group's project under `http(s)://groupname.example.io/projectname`.
## Quick Start
Read through [GitLab Pages Quick Start Guide][pages-quick] or watch the video tutorial on
[how to publish a website with GitLab Pages on GitLab.com from a forked project][video-pages-fork].
See also [All you Need to Know About GitLab Pages][pages-index-guide] for a list with all the resources we have for GitLab Pages.
### Explore the contents of `.gitlab-ci.yml`
The key thing about GitLab Pages is the `.gitlab-ci.yml` file, something that
......@@ -435,3 +444,6 @@ For a list of known issues, visit GitLab's [public issue tracker].
[public issue tracker]: https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name=Pages
[ce-14605]: https://gitlab.com/gitlab-org/gitlab-ce/issues/14605
[quick start guide]: ../../../ci/quick_start/README.md
[pages-index-guide]: ../../../pages/index.md
[pages-quick]: ../../../pages/getting_started_part_one.md
[video-pages-fork]: https://youtu.be/TWqh9MtT4Bg
......@@ -7,7 +7,9 @@ module API
version 'v3', using: :path do
mount ::API::V3::Boards
mount ::API::V3::Branches
mount ::API::V3::Commits
mount ::API::V3::DeployKeys
mount ::API::V3::Files
mount ::API::V3::Issues
mount ::API::V3::Labels
mount ::API::V3::Members
......
......@@ -97,13 +97,13 @@ module API
success Entities::RepoBranch
end
params do
requires :branch_name, type: String, desc: 'The name of the branch'
requires :branch, type: String, desc: 'The name of the branch'
requires :ref, type: String, desc: 'Create branch from commit sha or existing branch'
end
post ":id/repository/branches" do
authorize_push_project
result = CreateBranchService.new(user_project, current_user).
execute(params[:branch_name], params[:ref])
execute(params[:branch], params[:ref])
if result[:status] == :success
present result[:branch],
......@@ -126,7 +126,7 @@ module API
if result[:status] == :success
{
branch_name: params[:branch]
branch: params[:branch]
}
else
render_api_error!(result[:message], result[:return_code])
......
......@@ -41,7 +41,7 @@ module API
detail 'This feature was introduced in GitLab 8.13'
end
params do
requires :branch_name, type: String, desc: 'The name of branch'
requires :branch, type: String, desc: 'The name of branch'
requires :commit_message, type: String, desc: 'Commit message'
requires :actions, type: Array[Hash], desc: 'Actions to perform in commit'
optional :author_email, type: String, desc: 'Author email for commit'
......@@ -50,9 +50,8 @@ module API
post ":id/repository/commits" do
authorize! :push_code, user_project
attrs = declared_params
attrs[:start_branch] = attrs[:branch_name]
attrs[:target_branch] = attrs[:branch_name]
attrs = declared_params.merge(start_branch: declared_params[:branch], target_branch: declared_params[:branch])
attrs[:actions].map! do |action|
action[:action] = action[:action].to_sym
action[:file_path].slice!(0) if action[:file_path] && action[:file_path].start_with?('/')
......
......@@ -4,8 +4,8 @@ module API
def commit_params(attrs)
{
file_path: attrs[:file_path],
start_branch: attrs[:branch_name],
target_branch: attrs[:branch_name],
start_branch: attrs[:branch],
target_branch: attrs[:branch],
commit_message: attrs[:commit_message],
file_content: attrs[:content],
file_content_encoding: attrs[:encoding],
......@@ -17,13 +17,13 @@ module API
def commit_response(attrs)
{
file_path: attrs[:file_path],
branch_name: attrs[:branch_name]
branch: attrs[:branch]
}
end
params :simple_file_params do
requires :file_path, type: String, desc: 'The path to new file. Ex. lib/class.rb'
requires :branch_name, type: String, desc: 'The name of branch'
requires :branch, type: String, desc: 'The name of branch'
requires :commit_message, type: String, desc: 'Commit Message'
optional :author_email, type: String, desc: 'The email of the author'
optional :author_name, type: String, desc: 'The name of the author'
......
require 'mime/types'
module API
module V3
class Commits < Grape::API
include PaginationParams
before { authenticate! }
before { authorize! :download_code, user_project }
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects do
desc 'Get a project repository commits' do
success ::API::Entities::RepoCommit
end
params do
optional :ref_name, type: String, desc: 'The name of a repository branch or tag, if not given the default branch is used'
optional :since, type: DateTime, desc: 'Only commits after or in this date will be returned'
optional :until, type: DateTime, desc: 'Only commits before or in this date will be returned'
optional :page, type: Integer, default: 0, desc: 'The page for pagination'
optional :per_page, type: Integer, default: 20, desc: 'The number of results per page'
optional :path, type: String, desc: 'The file path'
end
get ":id/repository/commits" do
ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
offset = params[:page] * params[:per_page]
commits = user_project.repository.commits(ref,
path: params[:path],
limit: params[:per_page],
offset: offset,
after: params[:since],
before: params[:until])
present commits, with: ::API::Entities::RepoCommit
end
desc 'Commit multiple file changes as one commit' do
success ::API::Entities::RepoCommitDetail
detail 'This feature was introduced in GitLab 8.13'
end
params do
requires :branch_name, type: String, desc: 'The name of branch'
requires :commit_message, type: String, desc: 'Commit message'
requires :actions, type: Array[Hash], desc: 'Actions to perform in commit'
optional :author_email, type: String, desc: 'Author email for commit'
optional :author_name, type: String, desc: 'Author name for commit'
end
post ":id/repository/commits" do
authorize! :push_code, user_project
attrs = declared_params.dup
branch = attrs.delete(:branch_name)
attrs.merge!(branch: branch, start_branch: branch, target_branch: branch)
attrs[:actions].map! do |action|
action[:action] = action[:action].to_sym
action[:file_path].slice!(0) if action[:file_path] && action[:file_path].start_with?('/')
action[:previous_path].slice!(0) if action[:previous_path] && action[:previous_path].start_with?('/')
action
end
result = ::Files::MultiService.new(user_project, current_user, attrs).execute
if result[:status] == :success
commit_detail = user_project.repository.commits(result[:result], limit: 1).first
present commit_detail, with: ::API::Entities::RepoCommitDetail
else
render_api_error!(result[:message], 400)
end
end
desc 'Get a specific commit of a project' do
success ::API::Entities::RepoCommitDetail
failure [[404, 'Not Found']]
end
params do
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end
get ":id/repository/commits/:sha" do
commit = user_project.commit(params[:sha])
not_found! "Commit" unless commit
present commit, with: ::API::Entities::RepoCommitDetail
end
desc 'Get the diff for a specific commit of a project' do
failure [[404, 'Not Found']]
end
params do
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end
get ":id/repository/commits/:sha/diff" do
commit = user_project.commit(params[:sha])
not_found! "Commit" unless commit
commit.raw_diffs.to_a
end
desc "Get a commit's comments" do
success ::API::Entities::CommitNote
failure [[404, 'Not Found']]
end
params do
use :pagination
requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag'
end
get ':id/repository/commits/:sha/comments' do
commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit
notes = Note.where(commit_id: commit.id).order(:created_at)
present paginate(notes), with: ::API::Entities::CommitNote
end
desc 'Cherry pick commit into a branch' do
detail 'This feature was introduced in GitLab 8.15'
success ::API::Entities::RepoCommit
end
params do
requires :sha, type: String, desc: 'A commit sha to be cherry picked'
requires :branch, type: String, desc: 'The name of the branch'
end
post ':id/repository/commits/:sha/cherry_pick' do
authorize! :push_code, user_project
commit = user_project.commit(params[:sha])
not_found!('Commit') unless commit
branch = user_project.repository.find_branch(params[:branch])
not_found!('Branch') unless branch
commit_params = {
commit: commit,
create_merge_request: false,
source_project: user_project,
source_branch: commit.cherry_pick_branch_name,
target_branch: params[:branch]
}
result = ::Commits::CherryPickService.new(user_project, current_user, commit_params).execute
if result[:status] == :success
branch = user_project.repository.find_branch(params[:branch])
present user_project.repository.commit(branch.dereferenced_target), with: ::API::Entities::RepoCommit
else
render_api_error!(result[:message], 400)
end
end
desc 'Post comment to commit' do
success ::API::Entities::CommitNote
end
params do
requires :sha, type: String, regexp: /\A\h{6,40}\z/, desc: "The commit's SHA"
requires :note, type: String, desc: 'The text of the comment'
optional :path, type: String, desc: 'The file path'
given :path do
requires :line, type: Integer, desc: 'The line number'
requires :line_type, type: String, values: ['new', 'old'], default: 'new', desc: 'The type of the line'
end
end
post ':id/repository/commits/:sha/comments' do
commit = user_project.commit(params[:sha])
not_found! 'Commit' unless commit
opts = {
note: params[:note],
noteable_type: 'Commit',
commit_id: commit.id
}
if params[:path]
commit.raw_diffs(all_diffs: true).each do |diff|
next unless diff.new_path == params[:path]
lines = Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
lines.each do |line|
next unless line.new_pos == params[:line] && line.type == params[:line_type]
break opts[:line_code] = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
end
break if opts[:line_code]
end
opts[:type] = LegacyDiffNote.name if opts[:line_code]
end
note = ::Notes::CreateService.new(user_project, current_user, opts).execute
if note.save
present note, with: ::API::Entities::CommitNote
else
render_api_error!("Failed to save note #{note.errors.messages}", 400)
end
end
end
end
end
end
module API
module V3
class Files < Grape::API
helpers do
def commit_params(attrs)
{
file_path: attrs[:file_path],
start_branch: attrs[:branch],
target_branch: attrs[:branch],
commit_message: attrs[:commit_message],
file_content: attrs[:content],
file_content_encoding: attrs[:encoding],
author_email: attrs[:author_email],
author_name: attrs[:author_name]
}
end
def commit_response(attrs)
{
file_path: attrs[:file_path],
branch: attrs[:branch]
}
end
params :simple_file_params do
requires :file_path, type: String, desc: 'The path to new file. Ex. lib/class.rb'
requires :branch_name, type: String, desc: 'The name of branch'
requires :commit_message, type: String, desc: 'Commit Message'
optional :author_email, type: String, desc: 'The email of the author'
optional :author_name, type: String, desc: 'The name of the author'
end
params :extended_file_params do
use :simple_file_params
requires :content, type: String, desc: 'File content'
optional :encoding, type: String, values: %w[base64], desc: 'File encoding'
end
end
params do
requires :id, type: String, desc: 'The project ID'
end
resource :projects do
desc 'Get a file from repository'
params do
requires :file_path, type: String, desc: 'The path to the file. Ex. lib/class.rb'
requires :ref, type: String, desc: 'The name of branch, tag, or commit'
end
get ":id/repository/files" do
authorize! :download_code, user_project
commit = user_project.commit(params[:ref])
not_found!('Commit') unless commit
repo = user_project.repository
blob = repo.blob_at(commit.sha, params[:file_path])
not_found!('File') unless blob
blob.load_all_data!(repo)
status(200)
{
file_name: blob.name,
file_path: blob.path,
size: blob.size,
encoding: "base64",
content: Base64.strict_encode64(blob.data),
ref: params[:ref],
blob_id: blob.id,
commit_id: commit.id,
last_commit_id: repo.last_commit_id_for_path(commit.sha, params[:file_path])
}
end
desc 'Create new file in repository'
params do
use :extended_file_params
end
post ":id/repository/files" do
authorize! :push_code, user_project
file_params = declared_params(include_missing: false)
file_params[:branch] = file_params.delete(:branch_name)
result = ::Files::CreateService.new(user_project, current_user, commit_params(file_params)).execute
if result[:status] == :success
status(201)
commit_response(file_params)
else
render_api_error!(result[:message], 400)
end
end
desc 'Update existing file in repository'
params do
use :extended_file_params
end
put ":id/repository/files" do
authorize! :push_code, user_project
file_params = declared_params(include_missing: false)
file_params[:branch] = file_params.delete(:branch_name)
result = ::Files::UpdateService.new(user_project, current_user, commit_params(file_params)).execute
if result[:status] == :success
status(200)
commit_response(file_params)
else
http_status = result[:http_status] || 400
render_api_error!(result[:message], http_status)
end
end
desc 'Delete an existing file in repository'
params do
use :simple_file_params
end
delete ":id/repository/files" do
authorize! :push_code, user_project
file_params = declared_params(include_missing: false)
file_params[:branch] = file_params.delete(:branch_name)
result = ::Files::DestroyService.new(user_project, current_user, commit_params(file_params)).execute
if result[:status] == :success
status(200)
commit_response(file_params)
else
render_api_error!(result[:message], 400)
end
end
end
end
end
end
......@@ -32,7 +32,7 @@ module Gitlab
},
{
title: "Labels",
value: @resource.labels.any? ? @resource.label_names : "_None_",
value: @resource.labels.any? ? @resource.label_names.join(', ') : "_None_",
short: true
},
{
......
require 'spec_helper'
describe "Admin::Emails", feature: true, js: true do
include WaitForAjax
let!(:current_user) { login_as :admin }
let!(:group) { create(:group) }
let!(:project) { create(:project, namespace: group) }
describe "GET /admin/email" do
before do
visit admin_email_path
end
describe 'Recipient group select' do
it "includes groups and projects" do
find('.ajax-admin-email-select').click
wait_for_ajax
expect(page).to have_selector('.ajax-admin-email-dropdown li', count: 3)
group_names = page.all('.ajax-admin-email-dropdown li .group-name')
expect(group_names[0].text).to eq('All')
expect(group_names[1].text).to eq(group.name)
expect(find('.ajax-admin-email-dropdown li .project-name').text).to eq(project.name)
end
end
end
end
......@@ -26,6 +26,21 @@ describe Gitlab::ChatCommands::Presenters::IssueShow do
end
end
context 'with labels' do
let(:label) { create(:label, project: project, title: 'mep') }
let(:label1) { create(:label, project: project, title: 'mop') }
before do
issue.labels << [label, label1]
end
it 'shows the labels' do
labels = attachment[:fields].find { |f| f[:title] == 'Labels' }
expect(labels[:value]).to eq("mep, mop")
end
end
context 'confidential issue' do
let(:issue) { create(:issue, project: project) }
......
......@@ -285,7 +285,7 @@ describe API::Branches, api: true do
describe "POST /projects/:id/repository/branches" do
it "creates a new branch" do
post api("/projects/#{project.id}/repository/branches", user),
branch_name: 'feature1',
branch: 'feature1',
ref: branch_sha
expect(response).to have_http_status(201)
......@@ -296,14 +296,14 @@ describe API::Branches, api: true do
it "denies for user without push access" do
post api("/projects/#{project.id}/repository/branches", user2),
branch_name: branch_name,
branch: branch_name,
ref: branch_sha
expect(response).to have_http_status(403)
end
it 'returns 400 if branch name is invalid' do
post api("/projects/#{project.id}/repository/branches", user),
branch_name: 'new design',
branch: 'new design',
ref: branch_sha
expect(response).to have_http_status(400)
expect(json_response['message']).to eq('Branch name is invalid')
......@@ -311,12 +311,12 @@ describe API::Branches, api: true do
it 'returns 400 if branch already exists' do
post api("/projects/#{project.id}/repository/branches", user),
branch_name: 'new_design1',
branch: 'new_design1',
ref: branch_sha
expect(response).to have_http_status(201)
post api("/projects/#{project.id}/repository/branches", user),
branch_name: 'new_design1',
branch: 'new_design1',
ref: branch_sha
expect(response).to have_http_status(400)
expect(json_response['message']).to eq('Branch already exists')
......@@ -324,7 +324,7 @@ describe API::Branches, api: true do
it 'returns 400 if ref name is invalid' do
post api("/projects/#{project.id}/repository/branches", user),
branch_name: 'new_design3',
branch: 'new_design3',
ref: 'foo'
expect(response).to have_http_status(400)
expect(json_response['message']).to eq('Invalid reference name')
......@@ -339,14 +339,14 @@ describe API::Branches, api: true do
it "removes branch" do
delete api("/projects/#{project.id}/repository/branches/#{branch_name}", user)
expect(response).to have_http_status(200)
expect(json_response['branch_name']).to eq(branch_name)
expect(json_response['branch']).to eq(branch_name)
end
it "removes a branch with dots in the branch name" do
delete api("/projects/#{project.id}/repository/branches/with.1.2.3", user)
expect(response).to have_http_status(200)
expect(json_response['branch_name']).to eq("with.1.2.3")
expect(json_response['branch']).to eq("with.1.2.3")
end
it 'returns 404 if branch not exists' do
......
......@@ -107,7 +107,7 @@ describe API::Commits, api: true do
let(:message) { 'Created file' }
let!(:invalid_c_params) do
{
branch_name: 'master',
branch: 'master',
commit_message: message,
actions: [
{
......@@ -120,7 +120,7 @@ describe API::Commits, api: true do
end
let!(:valid_c_params) do
{
branch_name: 'master',
branch: 'master',
commit_message: message,
actions: [
{
......@@ -162,7 +162,7 @@ describe API::Commits, api: true do
let(:message) { 'Deleted file' }
let!(:invalid_d_params) do
{
branch_name: 'markdown',
branch: 'markdown',
commit_message: message,
actions: [
{
......@@ -174,7 +174,7 @@ describe API::Commits, api: true do
end
let!(:valid_d_params) do
{
branch_name: 'markdown',
branch: 'markdown',
commit_message: message,
actions: [
{
......@@ -203,7 +203,7 @@ describe API::Commits, api: true do
let(:message) { 'Moved file' }
let!(:invalid_m_params) do
{
branch_name: 'feature',
branch: 'feature',
commit_message: message,
actions: [
{
......@@ -217,7 +217,7 @@ describe API::Commits, api: true do
end
let!(:valid_m_params) do
{
branch_name: 'feature',
branch: 'feature',
commit_message: message,
actions: [
{
......@@ -248,7 +248,7 @@ describe API::Commits, api: true do
let(:message) { 'Updated file' }
let!(:invalid_u_params) do
{
branch_name: 'master',
branch: 'master',
commit_message: message,
actions: [
{
......@@ -261,7 +261,7 @@ describe API::Commits, api: true do
end
let!(:valid_u_params) do
{
branch_name: 'master',
branch: 'master',
commit_message: message,
actions: [
{
......@@ -291,7 +291,7 @@ describe API::Commits, api: true do
let(:message) { 'Multiple actions' }
let!(:invalid_mo_params) do
{
branch_name: 'master',
branch: 'master',
commit_message: message,
actions: [
{
......@@ -319,7 +319,7 @@ describe API::Commits, api: true do
end
let!(:valid_mo_params) do
{
branch_name: 'master',
branch: 'master',
commit_message: message,
actions: [
{
......
......@@ -104,7 +104,7 @@ describe API::Files, api: true do
let(:valid_params) do
{
file_path: 'newfile.rb',
branch_name: 'master',
branch: 'master',
content: 'puts 8',
commit_message: 'Added newfile'
}
......@@ -153,7 +153,7 @@ describe API::Files, api: true do
let(:valid_params) do
{
file_path: file_path,
branch_name: 'master',
branch: 'master',
content: 'puts 8',
commit_message: 'Changed file'
}
......@@ -193,7 +193,7 @@ describe API::Files, api: true do
let(:valid_params) do
{
file_path: file_path,
branch_name: 'master',
branch: 'master',
commit_message: 'Changed file'
}
end
......@@ -241,7 +241,7 @@ describe API::Files, api: true do
let(:put_params) do
{
file_path: file_path,
branch_name: 'master',
branch: 'master',
content: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=',
commit_message: 'Binary file with a \n should not be touched',
encoding: 'base64'
......
require 'spec_helper'
require 'mime/types'
describe API::V3::Commits, api: true do
include ApiHelpers
let(:user) { create(:user) }
let(:user2) { create(:user) }
let!(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
let!(:master) { create(:project_member, :master, user: user, project: project) }
let!(:guest) { create(:project_member, :guest, user: user2, project: project) }
let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') }
let!(:another_note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'another comment on a commit') }
before { project.team << [user, :reporter] }
describe "List repository commits" do
context "authorized user" do
before { project.team << [user2, :reporter] }
it "returns project commits" do
commit = project.repository.commit
get v3_api("/projects/#{project.id}/repository/commits", user)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.first['id']).to eq(commit.id)
expect(json_response.first['committer_name']).to eq(commit.committer_name)
expect(json_response.first['committer_email']).to eq(commit.committer_email)
end
end
context "unauthorized user" do
it "does not return project commits" do
get v3_api("/projects/#{project.id}/repository/commits")
expect(response).to have_http_status(401)
end
end
context "since optional parameter" do
it "returns project commits since provided parameter" do
commits = project.repository.commits("master")
since = commits.second.created_at
get v3_api("/projects/#{project.id}/repository/commits?since=#{since.utc.iso8601}", user)
expect(json_response.size).to eq 2
expect(json_response.first["id"]).to eq(commits.first.id)
expect(json_response.second["id"]).to eq(commits.second.id)
end
end
context "until optional parameter" do
it "returns project commits until provided parameter" do
commits = project.repository.commits("master")
before = commits.second.created_at
get v3_api("/projects/#{project.id}/repository/commits?until=#{before.utc.iso8601}", user)
if commits.size >= 20
expect(json_response.size).to eq(20)
else
expect(json_response.size).to eq(commits.size - 1)
end
expect(json_response.first["id"]).to eq(commits.second.id)
expect(json_response.second["id"]).to eq(commits.third.id)
end
end
context "invalid xmlschema date parameters" do
it "returns an invalid parameter error message" do
get v3_api("/projects/#{project.id}/repository/commits?since=invalid-date", user)
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('since is invalid')
end
end
context "path optional parameter" do
it "returns project commits matching provided path parameter" do
path = 'files/ruby/popen.rb'
get v3_api("/projects/#{project.id}/repository/commits?path=#{path}", user)
expect(json_response.size).to eq(3)
expect(json_response.first["id"]).to eq("570e7b2abdd848b95f2f578043fc23bd6f6fd24d")
end
end
end
describe "Create a commit with multiple files and actions" do
let!(:url) { "/projects/#{project.id}/repository/commits" }
it 'returns a 403 unauthorized for user without permissions' do
post v3_api(url, user2)
expect(response).to have_http_status(403)
end
it 'returns a 400 bad request if no params are given' do
post v3_api(url, user)
expect(response).to have_http_status(400)
end
context :create do
let(:message) { 'Created file' }
let!(:invalid_c_params) do
{
branch_name: 'master',
commit_message: message,
actions: [
{
action: 'create',
file_path: 'files/ruby/popen.rb',
content: 'puts 8'
}
]
}
end
let!(:valid_c_params) do
{
branch_name: 'master',
commit_message: message,
actions: [
{
action: 'create',
file_path: 'foo/bar/baz.txt',
content: 'puts 8'
}
]
}
end
it 'a new file in project repo' do
post v3_api(url, user), valid_c_params
expect(response).to have_http_status(201)
expect(json_response['title']).to eq(message)
expect(json_response['committer_name']).to eq(user.name)
expect(json_response['committer_email']).to eq(user.email)
end
it 'returns a 400 bad request if file exists' do
post v3_api(url, user), invalid_c_params
expect(response).to have_http_status(400)
end
context 'with project path in URL' do
let(:url) { "/projects/#{project.namespace.path}%2F#{project.path}/repository/commits" }
it 'a new file in project repo' do
post v3_api(url, user), valid_c_params
expect(response).to have_http_status(201)
end
end
end
context :delete do
let(:message) { 'Deleted file' }
let!(:invalid_d_params) do
{
branch_name: 'markdown',
commit_message: message,
actions: [
{
action: 'delete',
file_path: 'doc/api/projects.md'
}
]
}
end
let!(:valid_d_params) do
{
branch_name: 'markdown',
commit_message: message,
actions: [
{
action: 'delete',
file_path: 'doc/api/users.md'
}
]
}
end
it 'an existing file in project repo' do
post v3_api(url, user), valid_d_params
expect(response).to have_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post v3_api(url, user), invalid_d_params
expect(response).to have_http_status(400)
end
end
context :move do
let(:message) { 'Moved file' }
let!(:invalid_m_params) do
{
branch_name: 'feature',
commit_message: message,
actions: [
{
action: 'move',
file_path: 'CHANGELOG',
previous_path: 'VERSION',
content: '6.7.0.pre'
}
]
}
end
let!(:valid_m_params) do
{
branch_name: 'feature',
commit_message: message,
actions: [
{
action: 'move',
file_path: 'VERSION.txt',
previous_path: 'VERSION',
content: '6.7.0.pre'
}
]
}
end
it 'an existing file in project repo' do
post v3_api(url, user), valid_m_params
expect(response).to have_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post v3_api(url, user), invalid_m_params
expect(response).to have_http_status(400)
end
end
context :update do
let(:message) { 'Updated file' }
let!(:invalid_u_params) do
{
branch_name: 'master',
commit_message: message,
actions: [
{
action: 'update',
file_path: 'foo/bar.baz',
content: 'puts 8'
}
]
}
end
let!(:valid_u_params) do
{
branch_name: 'master',
commit_message: message,
actions: [
{
action: 'update',
file_path: 'files/ruby/popen.rb',
content: 'puts 8'
}
]
}
end
it 'an existing file in project repo' do
post v3_api(url, user), valid_u_params
expect(response).to have_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'returns a 400 bad request if file does not exist' do
post v3_api(url, user), invalid_u_params
expect(response).to have_http_status(400)
end
end
context "multiple operations" do
let(:message) { 'Multiple actions' }
let!(:invalid_mo_params) do
{
branch_name: 'master',
commit_message: message,
actions: [
{
action: 'create',
file_path: 'files/ruby/popen.rb',
content: 'puts 8'
},
{
action: 'delete',
file_path: 'doc/v3_api/projects.md'
},
{
action: 'move',
file_path: 'CHANGELOG',
previous_path: 'VERSION',
content: '6.7.0.pre'
},
{
action: 'update',
file_path: 'foo/bar.baz',
content: 'puts 8'
}
]
}
end
let!(:valid_mo_params) do
{
branch_name: 'master',
commit_message: message,
actions: [
{
action: 'create',
file_path: 'foo/bar/baz.txt',
content: 'puts 8'
},
{
action: 'delete',
file_path: 'Gemfile.zip'
},
{
action: 'move',
file_path: 'VERSION.txt',
previous_path: 'VERSION',
content: '6.7.0.pre'
},
{
action: 'update',
file_path: 'files/ruby/popen.rb',
content: 'puts 8'
}
]
}
end
it 'are commited as one in project repo' do
post v3_api(url, user), valid_mo_params
expect(response).to have_http_status(201)
expect(json_response['title']).to eq(message)
end
it 'return a 400 bad request if there are any issues' do
post v3_api(url, user), invalid_mo_params
expect(response).to have_http_status(400)
end
end
end
describe "Get a single commit" do
context "authorized user" do
it "returns a commit by sha" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
expect(response).to have_http_status(200)
expect(json_response['id']).to eq(project.repository.commit.id)
expect(json_response['title']).to eq(project.repository.commit.title)
expect(json_response['stats']['additions']).to eq(project.repository.commit.stats.additions)
expect(json_response['stats']['deletions']).to eq(project.repository.commit.stats.deletions)
expect(json_response['stats']['total']).to eq(project.repository.commit.stats.total)
end
it "returns a 404 error if not found" do
get v3_api("/projects/#{project.id}/repository/commits/invalid_sha", user)
expect(response).to have_http_status(404)
end
it "returns nil for commit without CI" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
expect(response).to have_http_status(200)
expect(json_response['status']).to be_nil
end
it "returns status for CI" do
pipeline = project.ensure_pipeline('master', project.repository.commit.sha)
pipeline.update(status: 'success')
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
expect(response).to have_http_status(200)
expect(json_response['status']).to eq(pipeline.status)
end
it "returns status for CI when pipeline is created" do
project.ensure_pipeline('master', project.repository.commit.sha)
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
expect(response).to have_http_status(200)
expect(json_response['status']).to eq("created")
end
end
context "unauthorized user" do
it "does not return the selected commit" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}")
expect(response).to have_http_status(401)
end
end
end
describe "Get the diff of a commit" do
context "authorized user" do
before { project.team << [user2, :reporter] }
it "returns the diff of the selected commit" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to be >= 1
expect(json_response.first.keys).to include "diff"
end
it "returns a 404 error if invalid commit" do
get v3_api("/projects/#{project.id}/repository/commits/invalid_sha/diff", user)
expect(response).to have_http_status(404)
end
end
context "unauthorized user" do
it "does not return the diff of the selected commit" do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff")
expect(response).to have_http_status(401)
end
end
end
describe 'Get the comments of a commit' do
context 'authorized user' do
it 'returns merge_request comments' do
get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user)
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.length).to eq(2)
expect(json_response.first['note']).to eq('a comment on a commit')
expect(json_response.first['author']['id']).to eq(user.id)
end
it 'returns a 404 error if merge_request_id not found' do
get v3_api("/projects/#{project.id}/repository/commits/1234ab/comments", user)
expect(response).to have_http_status(404)
end
end
context 'unauthorized user' do
it 'does not return the diff of the selected commit' do
get v3_api("/projects/#{project.id}/repository/commits/1234ab/comments")
expect(response).to have_http_status(401)
end
end
end
describe 'POST :id/repository/commits/:sha/cherry_pick' do
let(:master_pickable_commit) { project.commit('7d3b0f7cff5f37573aea97cebfd5692ea1689924') }
context 'authorized user' do
it 'cherry picks a commit' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'master'
expect(response).to have_http_status(201)
expect(json_response['title']).to eq(master_pickable_commit.title)
expect(json_response['message']).to eq(master_pickable_commit.message)
expect(json_response['author_name']).to eq(master_pickable_commit.author_name)
expect(json_response['committer_name']).to eq(user.name)
end
it 'returns 400 if commit is already included in the target branch' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'markdown'
expect(response).to have_http_status(400)
expect(json_response['message']).to eq('Sorry, we cannot cherry-pick this commit automatically.
A cherry-pick may have already been performed with this commit, or a more recent commit may have updated some of its content.')
end
it 'returns 400 if you are not allowed to push to the target branch' do
project.team << [user2, :developer]
protected_branch = create(:protected_branch, project: project, name: 'feature')
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user2), branch: protected_branch.name
expect(response).to have_http_status(400)
expect(json_response['message']).to eq('You are not allowed to push into this branch')
end
it 'returns 400 for missing parameters' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user)
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('branch is missing')
end
it 'returns 404 if commit is not found' do
post v3_api("/projects/#{project.id}/repository/commits/abcd0123/cherry_pick", user), branch: 'master'
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Commit Not Found')
end
it 'returns 404 if branch is not found' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user), branch: 'foo'
expect(response).to have_http_status(404)
expect(json_response['message']).to eq('404 Branch Not Found')
end
it 'returns 400 for missing parameters' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user)
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('branch is missing')
end
end
context 'unauthorized user' do
it 'does not cherry pick the commit' do
post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick"), branch: 'master'
expect(response).to have_http_status(401)
end
end
end
describe 'Post comment to commit' do
context 'authorized user' do
it 'returns comment' do
post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment'
expect(response).to have_http_status(201)
expect(json_response['note']).to eq('My comment')
expect(json_response['path']).to be_nil
expect(json_response['line']).to be_nil
expect(json_response['line_type']).to be_nil
end
it 'returns the inline comment' do
post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user), note: 'My comment', path: project.repository.commit.raw_diffs.first.new_path, line: 1, line_type: 'new'
expect(response).to have_http_status(201)
expect(json_response['note']).to eq('My comment')
expect(json_response['path']).to eq(project.repository.commit.raw_diffs.first.new_path)
expect(json_response['line']).to eq(1)
expect(json_response['line_type']).to eq('new')
end
it 'returns 400 if note is missing' do
post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments", user)
expect(response).to have_http_status(400)
end
it 'returns 404 if note is attached to non existent commit' do
post v3_api("/projects/#{project.id}/repository/commits/1234ab/comments", user), note: 'My comment'
expect(response).to have_http_status(404)
end
end
context 'unauthorized user' do
it 'does not return the diff of the selected commit' do
post v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/comments")
expect(response).to have_http_status(401)
end
end
end
end
require 'spec_helper'
describe API::V3::Files, api: true do
include ApiHelpers
let(:user) { create(:user) }
let!(:project) { create(:project, :repository, namespace: user.namespace ) }
let(:guest) { create(:user) { |u| project.add_guest(u) } }
let(:file_path) { 'files/ruby/popen.rb' }
let(:params) do
{
file_path: file_path,
ref: 'master'
}
end
let(:author_email) { FFaker::Internet.email }
# I have to remove periods from the end of the name
# This happened when the user's name had a suffix (i.e. "Sr.")
# This seems to be what git does under the hood. For example, this commit:
#
# $ git commit --author='Foo Sr. <foo@example.com>' -m 'Where's my trailing period?'
#
# results in this:
#
# $ git show --pretty
# ...
# Author: Foo Sr <foo@example.com>
# ...
let(:author_name) { FFaker::Name.name.chomp("\.") }
before { project.team << [user, :developer] }
describe "GET /projects/:id/repository/files" do
let(:route) { "/projects/#{project.id}/repository/files" }
shared_examples_for 'repository files' do
it "returns file info" do
get v3_api(route, current_user), params
expect(response).to have_http_status(200)
expect(json_response['file_path']).to eq(file_path)
expect(json_response['file_name']).to eq('popen.rb')
expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n")
end
context 'when no params are given' do
it_behaves_like '400 response' do
let(:request) { get v3_api(route, current_user) }
end
end
context 'when file_path does not exist' do
let(:params) do
{
file_path: 'app/models/application.rb',
ref: 'master',
}
end
it_behaves_like '404 response' do
let(:request) { get v3_api(route, current_user), params }
let(:message) { '404 File Not Found' }
end
end
context 'when repository is disabled' do
include_context 'disabled repository'
it_behaves_like '403 response' do
let(:request) { get v3_api(route, current_user), params }
end
end
end
context 'when unauthenticated', 'and project is public' do
it_behaves_like 'repository files' do
let(:project) { create(:project, :public) }
let(:current_user) { nil }
end
end
context 'when unauthenticated', 'and project is private' do
it_behaves_like '404 response' do
let(:request) { get v3_api(route), params }
let(:message) { '404 Project Not Found' }
end
end
context 'when authenticated', 'as a developer' do
it_behaves_like 'repository files' do
let(:current_user) { user }
end
end
context 'when authenticated', 'as a guest' do
it_behaves_like '403 response' do
let(:request) { get v3_api(route, guest), params }
end
end
end
describe "POST /projects/:id/repository/files" do
let(:valid_params) do
{
file_path: 'newfile.rb',
branch_name: 'master',
content: 'puts 8',
commit_message: 'Added newfile'
}
end
it "creates a new file in project repo" do
post v3_api("/projects/#{project.id}/repository/files", user), valid_params
expect(response).to have_http_status(201)
expect(json_response['file_path']).to eq('newfile.rb')
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
expect(last_commit.author_name).to eq(user.name)
end
it "returns a 400 bad request if no params given" do
post v3_api("/projects/#{project.id}/repository/files", user)
expect(response).to have_http_status(400)
end
it "returns a 400 if editor fails to create file" do
allow_any_instance_of(Repository).to receive(:commit_file).
and_return(false)
post v3_api("/projects/#{project.id}/repository/files", user), valid_params
expect(response).to have_http_status(400)
end
context "when specifying an author" do
it "creates a new file with the specified author" do
valid_params.merge!(author_email: author_email, author_name: author_name)
post v3_api("/projects/#{project.id}/repository/files", user), valid_params
expect(response).to have_http_status(201)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
expect(last_commit.author_name).to eq(author_name)
end
end
end
describe "PUT /projects/:id/repository/files" do
let(:valid_params) do
{
file_path: file_path,
branch_name: 'master',
content: 'puts 8',
commit_message: 'Changed file'
}
end
it "updates existing file in project repo" do
put v3_api("/projects/#{project.id}/repository/files", user), valid_params
expect(response).to have_http_status(200)
expect(json_response['file_path']).to eq(file_path)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
expect(last_commit.author_name).to eq(user.name)
end
it "returns a 400 bad request if no params given" do
put v3_api("/projects/#{project.id}/repository/files", user)
expect(response).to have_http_status(400)
end
context "when specifying an author" do
it "updates a file with the specified author" do
valid_params.merge!(author_email: author_email, author_name: author_name, content: "New content")
put v3_api("/projects/#{project.id}/repository/files", user), valid_params
expect(response).to have_http_status(200)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
expect(last_commit.author_name).to eq(author_name)
end
end
end
describe "DELETE /projects/:id/repository/files" do
let(:valid_params) do
{
file_path: file_path,
branch_name: 'master',
commit_message: 'Changed file'
}
end
it "deletes existing file in project repo" do
delete v3_api("/projects/#{project.id}/repository/files", user), valid_params
expect(response).to have_http_status(200)
expect(json_response['file_path']).to eq(file_path)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(user.email)
expect(last_commit.author_name).to eq(user.name)
end
it "returns a 400 bad request if no params given" do
delete v3_api("/projects/#{project.id}/repository/files", user)
expect(response).to have_http_status(400)
end
it "returns a 400 if fails to create file" do
allow_any_instance_of(Repository).to receive(:remove_file).and_return(false)
delete v3_api("/projects/#{project.id}/repository/files", user), valid_params
expect(response).to have_http_status(400)
end
context "when specifying an author" do
it "removes a file with the specified author" do
valid_params.merge!(author_email: author_email, author_name: author_name)
delete v3_api("/projects/#{project.id}/repository/files", user), valid_params
expect(response).to have_http_status(200)
last_commit = project.repository.commit.raw
expect(last_commit.author_email).to eq(author_email)
expect(last_commit.author_name).to eq(author_name)
end
end
end
describe "POST /projects/:id/repository/files with binary file" do
let(:file_path) { 'test.bin' }
let(:put_params) do
{
file_path: file_path,
branch_name: 'master',
content: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=',
commit_message: 'Binary file with a \n should not be touched',
encoding: 'base64'
}
end
let(:get_params) do
{
file_path: file_path,
ref: 'master',
}
end
before do
post v3_api("/projects/#{project.id}/repository/files", user), put_params
end
it "remains unchanged" do
get v3_api("/projects/#{project.id}/repository/files", user), get_params
expect(response).to have_http_status(200)
expect(json_response['file_path']).to eq(file_path)
expect(json_response['file_name']).to eq(file_path)
expect(json_response['content']).to eq(put_params[:content])
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment