Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
8ee94ef1
Commit
8ee94ef1
authored
Feb 25, 2021
by
Ahmet DEMIR
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add api /job to identify job using ci job token
This endpoint retrieve the job that generated a job token
parent
d10e408e
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
239 additions
and
32 deletions
+239
-32
changelogs/unreleased/51727-allow-job-identiy-self.yml
changelogs/unreleased/51727-allow-job-identiy-self.yml
+5
-0
doc/api/README.md
doc/api/README.md
+1
-0
doc/api/api_resources.md
doc/api/api_resources.md
+1
-0
doc/api/jobs.md
doc/api/jobs.md
+70
-0
lib/api/jobs.rb
lib/api/jobs.rb
+18
-3
spec/requests/api/jobs_spec.rb
spec/requests/api/jobs_spec.rb
+144
-29
No files found.
changelogs/unreleased/51727-allow-job-identiy-self.yml
0 → 100644
View file @
8ee94ef1
---
title
:
Add API endpoint for fetching a single job by CI_JOB_TOKEN
merge_request
:
51727
author
:
ahmet2mir
type
:
added
doc/api/README.md
View file @
8ee94ef1
...
@@ -211,6 +211,7 @@ to authenticate with the API:
...
@@ -211,6 +211,7 @@ to authenticate with the API:
-
[
Package Registry for PyPI
](
../user/packages/pypi_repository/index.md#authenticate-with-a-ci-job-token
)
-
[
Package Registry for PyPI
](
../user/packages/pypi_repository/index.md#authenticate-with-a-ci-job-token
)
-
[
Package Registry for generic packages
](
../user/packages/generic_packages/index.md#publish-a-generic-package-by-using-cicd
)
-
[
Package Registry for generic packages
](
../user/packages/generic_packages/index.md#publish-a-generic-package-by-using-cicd
)
-
[
Get job artifacts
](
job_artifacts.md#get-job-artifacts
)
-
[
Get job artifacts
](
job_artifacts.md#get-job-artifacts
)
-
[
Get job token's job
](
jobs.md#get-job-tokens-job
)
-
[
Pipeline triggers
](
pipeline_triggers.md
)
(
using
the
`token=`
parameter)
-
[
Pipeline triggers
](
pipeline_triggers.md
)
(
using
the
`token=`
parameter)
-
[
Release creation
](
releases/index.md#create-a-release
)
-
[
Release creation
](
releases/index.md#create-a-release
)
-
[
Terraform plan
](
../user/infrastructure/index.md
)
-
[
Terraform plan
](
../user/infrastructure/index.md
)
...
...
doc/api/api_resources.md
View file @
8ee94ef1
...
@@ -146,6 +146,7 @@ The following API resources are available outside of project and group contexts
...
@@ -146,6 +146,7 @@ The following API resources are available outside of project and group contexts
|
[
Instance clusters
](
instance_clusters.md
)
|
`/admin/clusters`
|
|
[
Instance clusters
](
instance_clusters.md
)
|
`/admin/clusters`
|
|
[
Issues
](
issues.md
)
|
`/issues`
(also available for groups and projects) |
|
[
Issues
](
issues.md
)
|
`/issues`
(also available for groups and projects) |
|
[
Issues Statistics
](
issues_statistics.md
)
|
`/issues_statistics`
(also available for groups and projects) |
|
[
Issues Statistics
](
issues_statistics.md
)
|
`/issues_statistics`
(also available for groups and projects) |
|
[
Jobs
](
jobs.md
)
|
`/job`
|
|
[
Keys
](
keys.md
)
|
`/keys`
|
|
[
Keys
](
keys.md
)
|
`/keys`
|
|
[
License
](
license.md
)
**(FREE SELF)**
|
`/license`
|
|
[
License
](
license.md
)
**(FREE SELF)**
|
`/license`
|
|
[
Markdown
](
markdown.md
)
|
`/markdown`
|
|
[
Markdown
](
markdown.md
)
|
`/markdown`
|
...
...
doc/api/jobs.md
View file @
8ee94ef1
...
@@ -380,6 +380,76 @@ Example of response
...
@@ -380,6 +380,76 @@ Example of response
]
]
```
```
## Get job token's job
Retrieve the job that generated a job token.
```
plaintext
GET /job
```
Examples
```
shell
curl
--header
"JOB-TOKEN: <your_job_token>"
"https://gitlab.example.com/api/v4/job"
curl
"https://gitlab.example.com/api/v4/job?job_token=<your_job_token>"
```
Example of response
```
json
{
"commit"
:
{
"author_email"
:
"admin@example.com"
,
"author_name"
:
"Administrator"
,
"created_at"
:
"2015-12-24T16:51:14.000+01:00"
,
"id"
:
"0ff3ae198f8601a285adcf5c0fff204ee6fba5fd"
,
"message"
:
"Test the CI integration."
,
"short_id"
:
"0ff3ae19"
,
"title"
:
"Test the CI integration."
},
"coverage"
:
null
,
"allow_failure"
:
false
,
"created_at"
:
"2015-12-24T15:51:21.880Z"
,
"started_at"
:
"2015-12-24T17:54:30.733Z"
,
"finished_at"
:
"2015-12-24T17:54:31.198Z"
,
"duration"
:
0.465
,
"artifacts_expire_at"
:
"2016-01-23T17:54:31.198Z"
,
"id"
:
8
,
"name"
:
"rubocop"
,
"pipeline"
:
{
"id"
:
6
,
"ref"
:
"master"
,
"sha"
:
"0ff3ae198f8601a285adcf5c0fff204ee6fba5fd"
,
"status"
:
"pending"
},
"ref"
:
"master"
,
"artifacts"
:
[],
"runner"
:
null
,
"stage"
:
"test"
,
"status"
:
"failed"
,
"tag"
:
false
,
"web_url"
:
"https://example.com/foo/bar/-/jobs/8"
,
"user"
:
{
"id"
:
1
,
"name"
:
"Administrator"
,
"username"
:
"root"
,
"state"
:
"active"
,
"avatar_url"
:
"http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
,
"web_url"
:
"http://gitlab.dev/root"
,
"created_at"
:
"2015-12-21T13:14:24.077Z"
,
"bio"
:
null
,
"location"
:
null
,
"public_email"
:
""
,
"skype"
:
""
,
"linkedin"
:
""
,
"twitter"
:
""
,
"website_url"
:
""
,
"organization"
:
""
}
}
```
## Get a single job
## Get a single job
Get a single job of a project
Get a single job of a project
...
...
lib/api/jobs.rb
View file @
8ee94ef1
...
@@ -8,10 +8,11 @@ module API
...
@@ -8,10 +8,11 @@ module API
feature_category
:continuous_integration
feature_category
:continuous_integration
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
end
resource
:projects
,
requirements:
API
::
NAMESPACE_OR_PROJECT_REQUIREMENTS
do
resource
:projects
,
requirements:
API
::
NAMESPACE_OR_PROJECT_REQUIREMENTS
do
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
end
helpers
do
helpers
do
params
:optional_scope
do
params
:optional_scope
do
optional
:scope
,
types:
[
String
,
Array
[
String
]],
desc:
'The scope of builds to show'
,
optional
:scope
,
types:
[
String
,
Array
[
String
]],
desc:
'The scope of builds to show'
,
...
@@ -168,6 +169,20 @@ module API
...
@@ -168,6 +169,20 @@ module API
end
end
end
end
resource
:job
do
desc
'Get current project using job token'
do
success
Entities
::
Ci
::
Job
end
route_setting
:authentication
,
job_token_allowed:
true
get
do
# current_authenticated_job will be nil if user is using
# a valid authentication that is not CI_JOB_TOKEN
not_found!
(
'Job'
)
unless
current_authenticated_job
present
current_authenticated_job
,
with:
Entities
::
Ci
::
Job
end
end
helpers
do
helpers
do
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
filter_builds
(
builds
,
scope
)
def
filter_builds
(
builds
,
scope
)
...
...
spec/requests/api/jobs_spec.rb
View file @
8ee94ef1
...
@@ -3,6 +3,9 @@
...
@@ -3,6 +3,9 @@
require
'spec_helper'
require
'spec_helper'
RSpec
.
describe
API
::
Jobs
do
RSpec
.
describe
API
::
Jobs
do
include
HttpBasicAuthHelpers
include
DependencyProxyHelpers
using
RSpec
::
Parameterized
::
TableSyntax
using
RSpec
::
Parameterized
::
TableSyntax
include
HttpIOHelpers
include
HttpIOHelpers
...
@@ -16,20 +19,150 @@ RSpec.describe API::Jobs do
...
@@ -16,20 +19,150 @@ RSpec.describe API::Jobs do
ref:
project
.
default_branch
)
ref:
project
.
default_branch
)
end
end
let!
(
:job
)
do
create
(
:ci_build
,
:success
,
:tags
,
pipeline:
pipeline
,
artifacts_expire_at:
1
.
day
.
since
)
end
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:api_user
)
{
user
}
let
(
:api_user
)
{
user
}
let
(
:reporter
)
{
create
(
:project_member
,
:reporter
,
project:
project
).
user
}
let
(
:reporter
)
{
create
(
:project_member
,
:reporter
,
project:
project
).
user
}
let
(
:guest
)
{
create
(
:project_member
,
:guest
,
project:
project
).
user
}
let
(
:guest
)
{
create
(
:project_member
,
:guest
,
project:
project
).
user
}
let
(
:running_job
)
do
create
(
:ci_build
,
:running
,
project:
project
,
user:
user
,
pipeline:
pipeline
,
artifacts_expire_at:
1
.
day
.
since
)
end
let!
(
:job
)
do
create
(
:ci_build
,
:success
,
:tags
,
pipeline:
pipeline
,
artifacts_expire_at:
1
.
day
.
since
)
end
before
do
before
do
project
.
add_developer
(
user
)
project
.
add_developer
(
user
)
end
end
shared_examples
'returns common pipeline data'
do
it
'returns common pipeline data'
do
expect
(
json_response
[
'pipeline'
]).
not_to
be_empty
expect
(
json_response
[
'pipeline'
][
'id'
]).
to
eq
jobx
.
pipeline
.
id
expect
(
json_response
[
'pipeline'
][
'ref'
]).
to
eq
jobx
.
pipeline
.
ref
expect
(
json_response
[
'pipeline'
][
'sha'
]).
to
eq
jobx
.
pipeline
.
sha
expect
(
json_response
[
'pipeline'
][
'status'
]).
to
eq
jobx
.
pipeline
.
status
end
end
shared_examples
'returns common job data'
do
it
'returns common job data'
do
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
[
'id'
]).
to
eq
(
jobx
.
id
)
expect
(
json_response
[
'status'
]).
to
eq
(
jobx
.
status
)
expect
(
json_response
[
'stage'
]).
to
eq
(
jobx
.
stage
)
expect
(
json_response
[
'name'
]).
to
eq
(
jobx
.
name
)
expect
(
json_response
[
'ref'
]).
to
eq
(
jobx
.
ref
)
expect
(
json_response
[
'tag'
]).
to
eq
(
jobx
.
tag
)
expect
(
json_response
[
'coverage'
]).
to
eq
(
jobx
.
coverage
)
expect
(
json_response
[
'allow_failure'
]).
to
eq
(
jobx
.
allow_failure
)
expect
(
Time
.
parse
(
json_response
[
'created_at'
])).
to
be_like_time
(
jobx
.
created_at
)
expect
(
Time
.
parse
(
json_response
[
'started_at'
])).
to
be_like_time
(
jobx
.
started_at
)
expect
(
Time
.
parse
(
json_response
[
'artifacts_expire_at'
])).
to
be_like_time
(
jobx
.
artifacts_expire_at
)
expect
(
json_response
[
'artifacts_file'
]).
to
be_nil
expect
(
json_response
[
'artifacts'
]).
to
be_an
Array
expect
(
json_response
[
'artifacts'
]).
to
be_empty
expect
(
json_response
[
'web_url'
]).
to
be_present
end
end
shared_examples
'returns unauthorized'
do
it
'returns unauthorized'
do
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
describe
'GET /job'
do
shared_context
'with auth headers'
do
let
(
:headers_with_token
)
{
header
}
let
(
:params_with_token
)
{
{}
}
end
shared_context
'with auth params'
do
let
(
:headers_with_token
)
{
{}
}
let
(
:params_with_token
)
{
param
}
end
shared_context
'without auth'
do
let
(
:headers_with_token
)
{
{}
}
let
(
:params_with_token
)
{
{}
}
end
before
do
|
example
|
unless
example
.
metadata
[
:skip_before_request
]
get
api
(
'/job'
),
headers:
headers_with_token
,
params:
params_with_token
end
end
context
'with job token authentication header'
do
include_context
'with auth headers'
do
let
(
:header
)
{
{
API
::
Helpers
::
Runner
::
JOB_TOKEN_HEADER
=>
running_job
.
token
}
}
end
it_behaves_like
'returns common job data'
do
let
(
:jobx
)
{
running_job
}
end
it
'returns specific job data'
do
expect
(
json_response
[
'finished_at'
]).
to
be_nil
end
it_behaves_like
'returns common pipeline data'
do
let
(
:jobx
)
{
running_job
}
end
end
context
'with job token authentication params'
do
include_context
'with auth params'
do
let
(
:param
)
{
{
job_token:
running_job
.
token
}
}
end
it_behaves_like
'returns common job data'
do
let
(
:jobx
)
{
running_job
}
end
it
'returns specific job data'
do
expect
(
json_response
[
'finished_at'
]).
to
be_nil
end
it_behaves_like
'returns common pipeline data'
do
let
(
:jobx
)
{
running_job
}
end
end
context
'with non running job'
do
include_context
'with auth headers'
do
let
(
:header
)
{
{
API
::
Helpers
::
Runner
::
JOB_TOKEN_HEADER
=>
job
.
token
}
}
end
it_behaves_like
'returns unauthorized'
end
context
'with basic auth header'
do
let
(
:personal_access_token
)
{
create
(
:personal_access_token
,
user:
user
)
}
let
(
:token
)
{
personal_access_token
.
token
}
include_context
'with auth headers'
do
let
(
:header
)
{
{
Gitlab
::
Auth
::
AuthFinders
::
PRIVATE_TOKEN_HEADER
=>
token
}
}
end
it
'does not return a job'
do
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'without authentication'
do
include_context
'without auth'
it_behaves_like
'returns unauthorized'
end
end
describe
'GET /projects/:id/jobs'
do
describe
'GET /projects/:id/jobs'
do
let
(
:query
)
{
{}
}
let
(
:query
)
{
{}
}
...
@@ -150,39 +283,21 @@ RSpec.describe API::Jobs do
...
@@ -150,39 +283,21 @@ RSpec.describe API::Jobs do
end
end
context
'authorized user'
do
context
'authorized user'
do
it_behaves_like
'returns common job data'
do
let
(
:jobx
)
{
job
}
end
it
'returns specific job data'
do
it
'returns specific job data'
do
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
[
'id'
]).
to
eq
(
job
.
id
)
expect
(
json_response
[
'status'
]).
to
eq
(
job
.
status
)
expect
(
json_response
[
'stage'
]).
to
eq
(
job
.
stage
)
expect
(
json_response
[
'name'
]).
to
eq
(
job
.
name
)
expect
(
json_response
[
'ref'
]).
to
eq
(
job
.
ref
)
expect
(
json_response
[
'tag'
]).
to
eq
(
job
.
tag
)
expect
(
json_response
[
'coverage'
]).
to
eq
(
job
.
coverage
)
expect
(
json_response
[
'allow_failure'
]).
to
eq
(
job
.
allow_failure
)
expect
(
Time
.
parse
(
json_response
[
'created_at'
])).
to
be_like_time
(
job
.
created_at
)
expect
(
Time
.
parse
(
json_response
[
'started_at'
])).
to
be_like_time
(
job
.
started_at
)
expect
(
Time
.
parse
(
json_response
[
'finished_at'
])).
to
be_like_time
(
job
.
finished_at
)
expect
(
Time
.
parse
(
json_response
[
'finished_at'
])).
to
be_like_time
(
job
.
finished_at
)
expect
(
Time
.
parse
(
json_response
[
'artifacts_expire_at'
])).
to
be_like_time
(
job
.
artifacts_expire_at
)
expect
(
json_response
[
'artifacts_file'
]).
to
be_nil
expect
(
json_response
[
'artifacts'
]).
to
be_an
Array
expect
(
json_response
[
'artifacts'
]).
to
be_empty
expect
(
json_response
[
'duration'
]).
to
eq
(
job
.
duration
)
expect
(
json_response
[
'duration'
]).
to
eq
(
job
.
duration
)
expect
(
json_response
[
'web_url'
]).
to
be_present
end
end
it_behaves_like
'a job with artifacts and trace'
,
result_is_array:
false
do
it_behaves_like
'a job with artifacts and trace'
,
result_is_array:
false
do
let
(
:api_endpoint
)
{
"/projects/
#{
project
.
id
}
/jobs/
#{
second_job
.
id
}
"
}
let
(
:api_endpoint
)
{
"/projects/
#{
project
.
id
}
/jobs/
#{
second_job
.
id
}
"
}
end
end
it
'returns pipeline data'
do
it_behaves_like
'returns common pipeline data'
do
json_job
=
json_response
let
(
:jobx
)
{
job
}
expect
(
json_job
[
'pipeline'
]).
not_to
be_empty
expect
(
json_job
[
'pipeline'
][
'id'
]).
to
eq
job
.
pipeline
.
id
expect
(
json_job
[
'pipeline'
][
'ref'
]).
to
eq
job
.
pipeline
.
ref
expect
(
json_job
[
'pipeline'
][
'sha'
]).
to
eq
job
.
pipeline
.
sha
expect
(
json_job
[
'pipeline'
][
'status'
]).
to
eq
job
.
pipeline
.
status
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment