fa-harness-tools 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +10 -9
- data/README.md +2 -0
- data/examples/create-deployment-tag/README.md +17 -0
- data/examples/create-deployment-tag/create-deployment-tag.sh +19 -0
- data/examples/production-preflight-checks/README.md +20 -0
- data/examples/production-preflight-checks/production-preflight-checks.sh +33 -0
- data/fa-harness-tools.gemspec +1 -1
- data/lib/fa-harness-tools/check_recent_deploy.rb +1 -1
- data/lib/fa-harness-tools/github_client.rb +41 -8
- data/lib/fa-harness-tools/version.rb +1 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43514c409f804648259a4b51366d9d4eec846c54badb0642a9fb3d916d13ad8d
|
4
|
+
data.tar.gz: 5c5e29f48aaf5e1f82a7cc608523086728e1085e89c9dde688c47db522b73b9f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 070f23a423e9e104c294eb3c6fd47fb0d45d5edc904be12cef90e1c83cd22e372b97e7544f9f3824006066e1c3a285274a3c10e0d6b7b0badf5360acaf2dcc86
|
7
|
+
data.tar.gz: 5cce7e38b1286181ae729433d5fdcd556dccb4c79500ee5b1c3cc471263ed767e714453ae10f910399954c4606c4ec1fbefbfec648e9f822a22ae151ba3b8ed8
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fa-harness-tools (1.0.
|
4
|
+
fa-harness-tools (1.0.5)
|
5
5
|
octokit (~> 4.0)
|
6
6
|
tzinfo (~> 2.0)
|
7
7
|
tzinfo-data (~> 1.0)
|
@@ -11,15 +11,16 @@ GEM
|
|
11
11
|
specs:
|
12
12
|
addressable (2.7.0)
|
13
13
|
public_suffix (>= 2.0.2, < 5.0)
|
14
|
-
concurrent-ruby (1.1.
|
14
|
+
concurrent-ruby (1.1.6)
|
15
15
|
diff-lcs (1.3)
|
16
|
-
faraday (0.
|
16
|
+
faraday (1.0.1)
|
17
17
|
multipart-post (>= 1.2, < 3)
|
18
18
|
multipart-post (2.1.1)
|
19
|
-
octokit (4.
|
19
|
+
octokit (4.18.0)
|
20
|
+
faraday (>= 0.9)
|
20
21
|
sawyer (~> 0.8.0, >= 0.5.3)
|
21
|
-
public_suffix (4.0.
|
22
|
-
rake (
|
22
|
+
public_suffix (4.0.5)
|
23
|
+
rake (13.0.1)
|
23
24
|
rspec (3.9.0)
|
24
25
|
rspec-core (~> 3.9.0)
|
25
26
|
rspec-expectations (~> 3.9.0)
|
@@ -37,9 +38,9 @@ GEM
|
|
37
38
|
addressable (>= 2.3.5)
|
38
39
|
faraday (> 0.8, < 2.0)
|
39
40
|
timecop (0.9.1)
|
40
|
-
tzinfo (2.0.
|
41
|
+
tzinfo (2.0.2)
|
41
42
|
concurrent-ruby (~> 1.0)
|
42
|
-
tzinfo-data (1.
|
43
|
+
tzinfo-data (1.2020.1)
|
43
44
|
tzinfo (>= 1.0.0)
|
44
45
|
|
45
46
|
PLATFORMS
|
@@ -48,7 +49,7 @@ PLATFORMS
|
|
48
49
|
DEPENDENCIES
|
49
50
|
bundler (~> 1.0)
|
50
51
|
fa-harness-tools!
|
51
|
-
rake (~>
|
52
|
+
rake (~> 13.0)
|
52
53
|
rspec (~> 3.8)
|
53
54
|
timecop (~> 0.9)
|
54
55
|
|
data/README.md
CHANGED
@@ -22,6 +22,8 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
Examples below use [variables defined by Harness](https://docs.harness.io/article/9dvxcegm90-variables) so should be suitable to use directly in Harness scripts.
|
24
24
|
|
25
|
+
Full scripts that can be used in Harness are available in the [examples/](examples/) directory.
|
26
|
+
|
25
27
|
### Required environment variables
|
26
28
|
|
27
29
|
* `GITHUB_OAUTH_TOKEN` must be exported, containing a valid [personal access token](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line) for GitHub
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Create deployment Git tags
|
2
|
+
|
3
|
+
## Purpose
|
4
|
+
|
5
|
+
Can be added to a Harness pipeline to add a Git tag on every deployment. The tags can then be used by the other pre-flight checks.
|
6
|
+
|
7
|
+
## Requirements
|
8
|
+
|
9
|
+
1. Add a GitHub OAuth token to the Harness secrets manager, named `github-oauth-token`
|
10
|
+
2. Assumes the artifact build number is the commit ID
|
11
|
+
3. fa-harness-tools is installed on the Harness delegates (`gem install -v $VERSION fa-harness-tools`)
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add the script to the Harness template library and then add to the last phase of the deployment workflow.
|
16
|
+
|
17
|
+
Define the `ONLY_ENVIRONMENT` variable input on the template, defaulting to `false`.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# Creates a Git tag to mark successful deployment with fa-harness-tools
|
4
|
+
#
|
5
|
+
# Optionally set ONLY_ENVIRONMENT to only tag when running a deployment in
|
6
|
+
# that Harness environment.
|
7
|
+
|
8
|
+
set -e
|
9
|
+
|
10
|
+
export GITHUB_OAUTH_TOKEN="${secrets.getValue("github-oauth-token")}"
|
11
|
+
|
12
|
+
if [ -z "${ONLY_ENVIRONMENT}" -o "${ONLY_ENVIRONMENT}" = "${env.name}" ]; then
|
13
|
+
create-deployment-tag \
|
14
|
+
--build-no "${artifact.buildNo}" \
|
15
|
+
--environment "${env.name}" \
|
16
|
+
--repository "${artifact.source.repositoryName}" \
|
17
|
+
--tagger-email "noreply@example.com" \
|
18
|
+
--tagger-name "Harness"
|
19
|
+
fi
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# Production pre-flight checks
|
2
|
+
|
3
|
+
## Purpose
|
4
|
+
|
5
|
+
Can be added to a Harness pipeline to enforce a set of strict requirements for production deployments:
|
6
|
+
|
7
|
+
1. Only deploy within the daily deployment window/schedule
|
8
|
+
2. Only deploy builds from the master branch
|
9
|
+
3. Automated (triggered) deployments may only deploy forwards
|
10
|
+
4. Manual deployments may only deploy forwards or roll back three deployments
|
11
|
+
|
12
|
+
## Requirements
|
13
|
+
|
14
|
+
1. Add a GitHub OAuth token to the Harness secrets manager, named `github-oauth-token`
|
15
|
+
2. Assumes the artifact build number is the commit ID
|
16
|
+
3. fa-harness-tools is installed on the Harness delegates (`gem install -v $VERSION fa-harness-tools`)
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add the script to the Harness template library and then add to an early phase of the deployment workflow.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
#
|
3
|
+
# Runs production deployment checks from fa-harness-tools
|
4
|
+
|
5
|
+
set -e
|
6
|
+
|
7
|
+
export GITHUB_OAUTH_TOKEN="${secrets.getValue("github-oauth-token")}"
|
8
|
+
|
9
|
+
run() {
|
10
|
+
CMD=$1
|
11
|
+
shift
|
12
|
+
$CMD \
|
13
|
+
--build-no "${artifact.buildNo}" \
|
14
|
+
--environment "${env.name}" \
|
15
|
+
--repository "${artifact.source.repositoryName}" \
|
16
|
+
"$@"
|
17
|
+
}
|
18
|
+
|
19
|
+
# 1. Check we're within the daily deployment schedule
|
20
|
+
check-schedule
|
21
|
+
|
22
|
+
# 2. Check the commit is on the master branch
|
23
|
+
run check-branch-protection
|
24
|
+
|
25
|
+
if [[ "${deploymentTriggeredBy}" =~ "Deployment Trigger" ]]; then
|
26
|
+
# 3. For automated deployments (trigger from CI), check deployment is fast-forward
|
27
|
+
run check-forward-deploy
|
28
|
+
else
|
29
|
+
# 3. For user deployments, check deployment is fast-forward or within last three deployments for rollbacks
|
30
|
+
run check-recent-deploy --allowed-rollback-count 3
|
31
|
+
fi
|
32
|
+
|
33
|
+
exit 0
|
data/fa-harness-tools.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_runtime_dependency "tzinfo-data", "~> 1.0"
|
32
32
|
|
33
33
|
spec.add_development_dependency "bundler", "~> 1.0"
|
34
|
-
spec.add_development_dependency "rake", "~>
|
34
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
35
35
|
spec.add_development_dependency "rspec", "~> 3.8"
|
36
36
|
spec.add_development_dependency "timecop", "~> 0.9"
|
37
37
|
end
|
@@ -42,7 +42,7 @@ module FaHarnessTools
|
|
42
42
|
return true, "first deploy"
|
43
43
|
end
|
44
44
|
|
45
|
-
latest_allowed_rev = latest_allowed_tag
|
45
|
+
latest_allowed_rev = @client.get_commit_sha_from_tag(latest_allowed_tag)
|
46
46
|
rev = @context.new_commit_sha
|
47
47
|
|
48
48
|
if @client.is_ancestor_of?(latest_allowed_rev, rev)
|
@@ -17,17 +17,24 @@ module FaHarnessTools
|
|
17
17
|
|
18
18
|
# Return all tags starting "harness-deploy-ENV-"
|
19
19
|
#
|
20
|
-
# Used to find deployments in an environment.
|
21
|
-
#
|
20
|
+
# Used to find deployments in an environment. Provides only the tag name
|
21
|
+
# and object, though that may be an annotated tag or a commit.
|
22
|
+
#
|
23
|
+
# Use #get_commit_sha_from_tag to reliably find the commit that a tag
|
24
|
+
# points to.
|
22
25
|
#
|
23
26
|
# @return [Array[Hash]] Array of tag data hash, or [] if none
|
24
27
|
def all_deploy_tags(prefix:, environment:)
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
# #refs is a much quicker way than #tags to pull back all tag names, so
|
29
|
+
# we prefer this and then fetch commit information only when we need it
|
30
|
+
@octokit.refs(owner_repo, "tags/#{prefix}-#{environment}-").map do |ref|
|
31
|
+
{
|
32
|
+
name: ref[:ref][10..-1], # remove refs/tags/ prefix
|
33
|
+
object: ref[:object],
|
34
|
+
}
|
28
35
|
end
|
29
|
-
|
30
|
-
|
36
|
+
rescue Octokit::NotFound
|
37
|
+
[]
|
31
38
|
end
|
32
39
|
|
33
40
|
# Return the last (when sorted) tag starting "harness-deploy-ENV-"
|
@@ -39,7 +46,11 @@ module FaHarnessTools
|
|
39
46
|
def last_deploy_tag(prefix:, environment:)
|
40
47
|
last_tag = all_deploy_tags(prefix: prefix, environment: environment).
|
41
48
|
sort_by { |tag| tag[:name] }.last
|
42
|
-
|
49
|
+
return nil unless last_tag
|
50
|
+
|
51
|
+
last_tag.merge(
|
52
|
+
commit: { sha: get_commit_sha_from_tag(last_tag) },
|
53
|
+
)
|
43
54
|
end
|
44
55
|
|
45
56
|
# Return a full commit SHA from a short SHA
|
@@ -52,6 +63,28 @@ module FaHarnessTools
|
|
52
63
|
commit[:sha]
|
53
64
|
end
|
54
65
|
|
66
|
+
# Return a full commit SHA from a tag
|
67
|
+
#
|
68
|
+
# The `tag` argument should be a Hash of tag data with an :object that can
|
69
|
+
# either be an annotated tag or a commit object.
|
70
|
+
#
|
71
|
+
# @return [String] Full commit SHA
|
72
|
+
# @raise [LookupError] If tag cannot be found
|
73
|
+
def get_commit_sha_from_tag(tag)
|
74
|
+
case tag[:object][:type]
|
75
|
+
when "commit"
|
76
|
+
tag[:object][:sha]
|
77
|
+
when "tag"
|
78
|
+
# When a tag points to a tag, recurse into it until we find a commit object
|
79
|
+
refed_tag = @octokit.tag(owner_repo, tag[:object][:sha])
|
80
|
+
get_commit_sha_from_tag(refed_tag.to_h.merge(tag.slice(:name)))
|
81
|
+
else
|
82
|
+
raise LookupError, "Tag #{tag[:name]} points to a non-commit object (#{tag[:object].inspect})"
|
83
|
+
end
|
84
|
+
rescue Octokit::NotFound
|
85
|
+
raise LookupError, "Unable to find tag #{tag.inspect} in Git repo"
|
86
|
+
end
|
87
|
+
|
55
88
|
# Checks if <ancestor> is an ancestor of <commit>
|
56
89
|
#
|
57
90
|
# i.e. commit and ancestor are directly related
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fa-harness-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- FreeAgent
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: octokit
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '13.0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '13.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,6 +133,10 @@ files:
|
|
133
133
|
- Rakefile
|
134
134
|
- bin/console
|
135
135
|
- bin/setup
|
136
|
+
- examples/create-deployment-tag/README.md
|
137
|
+
- examples/create-deployment-tag/create-deployment-tag.sh
|
138
|
+
- examples/production-preflight-checks/README.md
|
139
|
+
- examples/production-preflight-checks/production-preflight-checks.sh
|
136
140
|
- exe/check-branch-protection
|
137
141
|
- exe/check-forward-deploy
|
138
142
|
- exe/check-recent-deploy
|