tenma 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5534058ddf106c8eee32ae05e4ad741d4b859443
4
+ data.tar.gz: 0c59a6c5668b3d646af0e2e65f17b9c526200410
5
+ SHA512:
6
+ metadata.gz: 659fa12c1f0d0286b3f0fced66d8bb88a2a05a9f8f778df8f55adb8d97732ada35328946c98cb41ae2c3c6fdc3e3958c1151cde36cff83c2672c92bc1ca36361
7
+ data.tar.gz: 2ae6c1eb444d7e9ced28ed58b8810424db4d69a973985ce985e8a9d552f6d9bdfeb9a084d95fa441a08bbdc4b8a0982487800ddfba84d730a8106463d35c4184
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.1
5
+ before_install: gem install bundler -v 1.15.4
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in tenma.gemspec
6
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 hisaichi5518
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,196 @@
1
+ # 天満(Tenma)
2
+
3
+ Tenma is command line tool for mobile application development.
4
+
5
+ - [:kissing_closed_eyes:Prepare for mobile application release.](README.md#kissing_closed_eyeskissing_closed_eyes-prepare-for-mobile-application-release-kissing_closed_eyeskissing_closed_eyes)
6
+ - [:relaxed:Manipulate "Android-remote-build" instance.](README.md#relaxedrelaxed-manipulate-android-remote-build-instance-relaxedrelaxed)
7
+
8
+ ## Usage
9
+
10
+ ### :kissing_closed_eyes::kissing_closed_eyes: Prepare for mobile application release. :kissing_closed_eyes::kissing_closed_eyes:
11
+
12
+ #### 1. :paperclip: Set `TENMA_GITHUB_TOKEN` environment.
13
+
14
+ [Github Personal access tokens](https://github.com/settings/tokens) is required. The only necessary scope is repo.
15
+
16
+ Set `TENMA_GITHUB_TOKEN` at .zshrc or .bashrc.
17
+ ```
18
+ export TENMA_GITHUB_TOKEN=your-github-personal-access-token
19
+ ```
20
+
21
+ #### 2. :memo: Create `tenma/prepare.yml`
22
+
23
+ ```yaml
24
+ github:
25
+ web_url: "https://github.com/"
26
+ api_url: "https://github.com/api/v3"
27
+ owner: "hisaichi5518"
28
+ repo: "tenma"
29
+ kpt_issue:
30
+ labels:
31
+ - KPT
32
+ title: "v<%= @context.options.raw.version %> KPT"
33
+ body: |
34
+ KPT issue's body
35
+ release_issue:
36
+ labels:
37
+ - Release
38
+ title: "v<%= @context.options.raw.version %> Release"
39
+ body: |
40
+ Release issue's body
41
+ release_branch:
42
+ version_file: "VERSION"
43
+ hotfix:
44
+ base: "master"
45
+ branch: "hotfix/v<%= @context.options.raw.version %>"
46
+ normal:
47
+ base: "develop"
48
+ branch: "release/v<%= @context.options.raw.version %>"
49
+ changelogs:
50
+ - path: "./fastlane/metadata/android/ja-JP/changelogs"
51
+ body: |
52
+ changelog's body
53
+ release_pullreq:
54
+ bases:
55
+ - master
56
+ - develop
57
+ labels:
58
+ - ReleaseBranch
59
+ title: "【<%= base_branch %>】<%= @context.options.raw.version %> Release"
60
+ body: |
61
+ Release pull-request's body
62
+ ```
63
+
64
+ #### 3. :runner: Run command
65
+
66
+ Run following command, if you want to create KPT issue and Release issue.
67
+ ```
68
+ bundle exec tenma prepare --kpt-issue --release-issue --version 7.14.0
69
+ ```
70
+
71
+ Run following command, if you want to create Release branch and Release pull-requests.
72
+ ```
73
+ bundle exec tenma prepare --release-branch --release-pullreqs --version 7.14.0
74
+ ```
75
+
76
+ #### 4. :helicopter: Finish!
77
+
78
+ Execute the `tenma help prepare` command, If you want more information.
79
+
80
+ Ex)
81
+ ```
82
+ $ bundle exec help prepare
83
+ Usage:
84
+ tenma prepare --version=VERSION
85
+
86
+ Options:
87
+ [--kpt-issue], [--no-kpt-issue]
88
+ [--release-issue], [--no-release-issue]
89
+ [--release-branch], [--no-release-branch]
90
+ [--release-pullreqs], [--no-release-pullreqs]
91
+ [--config-file=CONFIG-FILE]
92
+ # Default: ./tenma/prepare.yml
93
+ [--github-token=GITHUB-TOKEN]
94
+ # Default: <Github personal access token>
95
+ --version=VERSION
96
+ ```
97
+
98
+ ### :relaxed::relaxed: Manipulate "Android-remote-build" instance. :relaxed::relaxed:
99
+
100
+ #### 1. :paperclip: Set `TENMA_ICHIBA_INSTANCE_PROJECT` environment.
101
+
102
+ Set `TENMA_ICHIBA_INSTANCE_PROJECT` at .zshrc or .bashrc.
103
+
104
+ ```
105
+ export TENMA_ICHIBA_INSTANCE_PROJECT=your-gcp-project
106
+ ```
107
+
108
+ #### 2. :memo: Create `tenma/ichiba.yml`
109
+
110
+ ```yaml
111
+ android_sdk:
112
+ license: "your license key"
113
+ update_list:
114
+ - platform-tools
115
+ - build-tools-27.0.3
116
+ - android-27
117
+ - extra-android-m2repository
118
+ - extra-google-m2repository
119
+ - extra-google-google_play_services
120
+ ```
121
+
122
+ #### 3. :runner: Run command
123
+
124
+ Run following command, if you want to create and provision remote-build instance.
125
+ ```
126
+ bundle exec tenma ichiba --create-instance --provision-instance
127
+ ```
128
+
129
+ Run following command, if you want to delete remote-build instance.
130
+ ```
131
+ bundle exec tenma ichiba --delete-instance
132
+ ```
133
+
134
+ #### 4. :helicopter: Finish!
135
+
136
+ Execute the `tenma help ichiba` command, If you want more information.
137
+
138
+ Ex)
139
+ ```
140
+ $ bundle exec tenma help ichiba
141
+ Usage:
142
+ tenma ichiba --instance-disk-size=N --instance-machine-type=INSTANCE-MACHINE-TYPE --instance-name=INSTANCE-NAME --instance-project=INSTANCE-PROJECT --instance-zone=INSTANCE-ZONE --node-yaml=NODE-YAML --ssh-key-file=SSH-KEY-FILE
143
+
144
+ Options:
145
+ [--create-instance], [--no-create-instance]
146
+ [--provision-instance], [--no-provision-instance]
147
+ [--delete-instance], [--no-delete-instance]
148
+ [--restart-instance], [--no-restart-instance]
149
+ --instance-name=INSTANCE-NAME
150
+ # Default: remote-build
151
+ --instance-zone=INSTANCE-ZONE
152
+ # Default: asia-northeast1-c
153
+ --instance-project=INSTANCE-PROJECT
154
+ --instance-machine-type=INSTANCE-MACHINE-TYPE
155
+ # Default: n1-highcpu-16
156
+ --instance-disk-size=N
157
+ # Default: 20
158
+ --ssh-key-file=SSH-KEY-FILE
159
+ # Default: ~/.ssh/id_rsa
160
+ --node-yaml=NODE-YAML
161
+ # Default: ./tenma/ichiba.yml
162
+ ```
163
+
164
+ ## Installation
165
+
166
+ Add this line to your application's Gemfile:
167
+
168
+ ```ruby
169
+ gem 'tenma'
170
+ ```
171
+
172
+ And then execute:
173
+
174
+ $ bundle
175
+
176
+ Or install it yourself as:
177
+
178
+ $ gem install tenma
179
+
180
+ ## Development
181
+
182
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
183
+
184
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
185
+
186
+ ## Contributing
187
+
188
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hisaichi5518/tenma.
189
+
190
+ ## License
191
+
192
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
193
+
194
+ ## :eyes::eyes: See also :eyes::eyes:
195
+
196
+ [モバイルアプリのリリース作業自動化への取り組み - ペパボテックブログ](https://tech.pepabo.com/2017/10/06/improve-application-release-flow/)
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "tenma"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tenma/cli'
4
+
5
+ Tenma::CLI.start
@@ -0,0 +1,5 @@
1
+ require "tenma/version"
2
+
3
+ module Tenma
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,36 @@
1
+ require 'thor'
2
+ require 'tenma/prepare/command'
3
+ require 'tenma/ichiba/command'
4
+
5
+ module Tenma
6
+ class CLI < ::Thor
7
+
8
+ desc "prepare", "Prepare for mobile application release."
9
+ option "kpt-issue", type: :boolean
10
+ option "release-issue", type: :boolean
11
+ option "release-branch", type: :boolean
12
+ option "release-pullreqs", type: :boolean
13
+ option "config-file", type: :string, default: File.expand_path("tenma/prepare.yml")
14
+ option "github-token", type: :string, default: ENV["TENMA_GITHUB_TOKEN"]
15
+ option "version", type: :string, required: true
16
+ def prepare
17
+ Tenma::Prepare::Command.new(self).execute
18
+ end
19
+
20
+ desc "ichiba", "Manipulate remote build instance for android application."
21
+ option "create-instance", type: :boolean
22
+ option "provision-instance", type: :boolean
23
+ option "delete-instance", type: :boolean
24
+ option "restart-instance", type: :boolean
25
+ option "instance-name", type: :string, default: "remote-build", required: true
26
+ option "instance-zone", type: :string, default: "asia-northeast1-c", required: true
27
+ option "instance-project", type: :string, default: ENV["TENMA_ICHIBA_INSTANCE_PROJECT"], required: true
28
+ option "instance-machine-type", type: :string, default: "n1-highcpu-16", required: true
29
+ option "instance-disk-size", type: :numeric, default: 20, required: true
30
+ option "ssh-key-file", type: :string, default: File.expand_path("~/.ssh/id_rsa"), required: true
31
+ option "node-yaml", type: :string, default: File.expand_path("tenma/ichiba.yml"), required: true
32
+ def ichiba
33
+ Tenma::Ichiba::Command.new(self).execute
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ require 'tenma/ichiba/context'
2
+ require 'tenma/ichiba/validator'
3
+ require 'tenma/ichiba/instance'
4
+
5
+ module Tenma
6
+ module Ichiba
7
+ class Command
8
+ def initialize(cli)
9
+ @cli = cli
10
+ end
11
+
12
+ def execute
13
+ @context = Tenma::Ichiba::Context.new.load!(@cli.options)
14
+
15
+ Tenma::Ichiba::Validator.new(@context).validate!
16
+
17
+ if @context.options.create_instance?
18
+ Tenma::Ichiba::Instance.new(@context).create
19
+ end
20
+
21
+ if @context.options.provision_instance?
22
+ Tenma::Ichiba::Instance.new(@context).provision
23
+ end
24
+
25
+ if @context.options.restart_instance?
26
+ Tenma::Ichiba::Instance.new(@context).restart
27
+ end
28
+
29
+ if @context.options.delete_instance?
30
+ Tenma::Ichiba::Instance.new(@context).delete
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ require 'tenma/ichiba/options'
2
+
3
+ module Tenma
4
+ module Ichiba
5
+ class Context
6
+
7
+ USER = ENV["USER"]
8
+
9
+ attr_reader :options
10
+
11
+ def load!(opts)
12
+ @options = Tenma::Ichiba::Options.new(opts)
13
+ self
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,61 @@
1
+ require 'itamae/runner'
2
+
3
+ module Tenma
4
+ module Ichiba
5
+ class Instance
6
+
7
+ attr_reader :context, :name, :type, :zone, :project, :disk_size
8
+ def initialize(context)
9
+ @context = context
10
+ @name = @context.options.raw.instance_name
11
+ @type = @context.options.raw.instance_machine_type
12
+ @zone = @context.options.raw.instance_zone
13
+ @project = @context.options.raw.instance_project
14
+ @disk_size = @context.options.raw.instance_disk_size
15
+ end
16
+
17
+ def create
18
+ puts "Create instance..."
19
+ puts `gcloud compute instances create #{name} --image-family ubuntu-1710 --image-project ubuntu-os-cloud --preemptible --machine-type #{type} --zone #{zone} --project #{project} --boot-disk-size #{disk_size}GB`
20
+ end
21
+
22
+ def provision
23
+ file = context.options.raw.ssh_key_file
24
+
25
+ if @context.options.create_instance?
26
+ # Immediately after launching the instance, it takes time to start up, so it can not lead to SSH.
27
+ puts "sleep 60 sec"
28
+ sleep 60 # sec
29
+ end
30
+
31
+ # In order to execute Itamae, it is necessary to set up ssh config.
32
+ puts `gcloud compute config-ssh --remove --ssh-key-file #{file} --project #{project}`
33
+ puts `gcloud compute config-ssh --ssh-key-file #{file} --project #{project}`
34
+
35
+ puts "Provision instance..."
36
+ role_file = File.expand_path('../itamae/roles/remote.rb', __FILE__)
37
+ node_yaml = context.options.raw.node_yaml
38
+ Itamae::Runner.run([role_file], :ssh, {
39
+ host: "#{name}.#{zone}.#{project}",
40
+ node_yaml: node_yaml,
41
+ color: false,
42
+ sudo: true,
43
+ shell: "/bin/sh",
44
+ log_level: "info",
45
+ })
46
+ end
47
+
48
+ def delete
49
+ puts "Delete instance..."
50
+ puts `gcloud compute instances delete #{name} --delete-disks all --quiet --zone #{zone} --project #{project}`
51
+ end
52
+
53
+ def restart
54
+ puts "Reset instance..."
55
+ puts `gcloud compute instances reset #{name} --zone #{zone} --project #{project}`
56
+ puts "Start instance..."
57
+ puts `gcloud compute instances start #{name} --zone #{zone} --project #{project}`
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,2 @@
1
+ include_recipe "./dependency"
2
+ include_recipe "./install"
@@ -0,0 +1,9 @@
1
+ if node[:kernel][:machine] == 'x86_64'
2
+ # Install lib32stdc++6 lib32z1
3
+ %w(lib32stdc++6 lib32z1).each do |pkg|
4
+ package pkg
5
+ end
6
+ end
7
+
8
+ # Install Java8
9
+ package "openjdk-8-jdk-headless"
@@ -0,0 +1,42 @@
1
+ directory "./android" do
2
+ action :create
3
+ owner Tenma::Ichiba::Context::USER
4
+ end
5
+
6
+ android_sdk_url = "http://dl.google.com/android/android-sdk_r24.3.3-linux.tgz"
7
+ execute "curl -L \"#{android_sdk_url}\" | tar --no-same-owner -xz -C ./android" do
8
+ not_if "test -e ./android/android-sdk-linux"
9
+ user Tenma::Ichiba::Context::USER
10
+ end
11
+
12
+ execute "echo 'export ANDROID_HOME=/home/#{Tenma::Ichiba::Context::USER}/android/android-sdk-linux' >> ~/.bash_profile" do
13
+ not_if "cat ~/.bash_profile | grep ANDROID_HOME"
14
+ user Tenma::Ichiba::Context::USER
15
+ end
16
+
17
+ # Setup license key
18
+ if node[:android_sdk][:license]
19
+ directory "./android/android-sdk-linux/licenses" do
20
+ action :create
21
+ owner Tenma::Ichiba::Context::USER
22
+ end
23
+
24
+ execute "echo '#{node[:android_sdk][:license]}' >> ./android/android-sdk-linux/licenses/android-sdk-license" do
25
+ not_if "test -e ./android/android-sdk-linux/licenses/android-sdk-license"
26
+ user Tenma::Ichiba::Context::USER
27
+ end
28
+ end
29
+
30
+ # Update sdk
31
+ if node[:android_sdk][:update_list]
32
+ template "./android/install-android-sdk-components.sh" do
33
+ mode "0755"
34
+ source "templates/install-android-sdk-components.sh.erb"
35
+ variables(update_list: node[:android_sdk][:update_list].join(","))
36
+ user Tenma::Ichiba::Context::USER
37
+ end
38
+
39
+ execute "./android/install-android-sdk-components.sh" do
40
+ user Tenma::Ichiba::Context::USER
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ echo y | ./android/android-sdk-linux/tools/android update sdk --no-ui --all --filter "<%= @update_list %>"
@@ -0,0 +1,2 @@
1
+ execute "sudo apt update" do
2
+ end
@@ -0,0 +1,10 @@
1
+ directory "./mainframer/android" do
2
+ action :create
3
+ owner Tenma::Ichiba::Context::USER
4
+ end
5
+
6
+ file "./mainframer/android/local.properties" do
7
+ action :create
8
+ owner Tenma::Ichiba::Context::USER
9
+ content "sdk.dir=/home/#{Tenma::Ichiba::Context::USER}/android/android-sdk-linux"
10
+ end
@@ -0,0 +1,3 @@
1
+ include_recipe "../cookbooks/initialize"
2
+ include_recipe "../cookbooks/android-sdk"
3
+ include_recipe "../cookbooks/mainframer"
@@ -0,0 +1,34 @@
1
+ require "hashie/mash"
2
+
3
+ module Tenma
4
+ module Ichiba
5
+ class Options
6
+
7
+ attr_reader :raw
8
+ def initialize(opts)
9
+ @raw = Hashie::Mash.new(opts.map { |k, v| [k.gsub(/-/, "_"), v] }.to_h)
10
+ end
11
+
12
+ def create_instance?
13
+ return !!raw.create_instance
14
+ end
15
+
16
+ def delete_instance?
17
+ return !!raw.delete_instance
18
+ end
19
+
20
+ def delete_all_instances?
21
+ return !!raw.delete_all_instances
22
+ end
23
+
24
+ def provision_instance?
25
+ return !!raw.provision_instance
26
+ end
27
+
28
+ def restart_instance?
29
+ return !!raw.restart_instance
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ module Tenma
2
+ module Ichiba
3
+ class Validator
4
+ attr_reader :context
5
+ def initialize(context)
6
+ @context = context
7
+ end
8
+
9
+ def validate!
10
+ if !command?("gcloud")
11
+ raise ValidationException, "required gcloud command"
12
+ end
13
+
14
+ if !File.exist?(context.options.raw.node_yaml)
15
+ raise ValidationException, "Can't find #{context.options.raw.node_yaml}"
16
+ end
17
+
18
+ if context.options.provision_instance? && (ENV["USER"].nil? || ENV["USER"].empty?)
19
+ raise ValidationException, "ENV[USER] is nil or empty..."
20
+ end
21
+ end
22
+
23
+ def command?(command)
24
+ system "which #{command} > /dev/null 2>&1"
25
+ end
26
+
27
+ class ValidationException < Exception
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ require 'tenma/prepare/context'
2
+ require 'tenma/prepare/kpt_issue'
3
+ require 'tenma/prepare/release_issue'
4
+ require 'tenma/prepare/release_branch'
5
+ require 'tenma/prepare/release_pullreqs'
6
+
7
+ module Tenma
8
+ module Prepare
9
+ class Command
10
+ def initialize(cli)
11
+ @cli = cli
12
+ end
13
+
14
+ def execute
15
+ @context = Tenma::Prepare::Context.new.load!(@cli.options)
16
+ if @context.options.create_kpt_issue?
17
+ Tenma::Prepare::KptIssue.new(@context).create
18
+ end
19
+
20
+ if @context.options.create_release_issue?
21
+ Tenma::Prepare::ReleaseIssue.new(@context).create
22
+ end
23
+
24
+ if @context.options.create_release_branch?
25
+ Tenma::Prepare::ReleaseBranch.new(@context).create
26
+ end
27
+
28
+ if @context.options.create_release_pullreqs?
29
+ Tenma::Prepare::ReleasePullreqs.new(@context).create
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ require 'yaml'
2
+ require 'hashie/mash'
3
+
4
+ module Tenma
5
+ module Prepare
6
+ class Config
7
+ attr_reader :raw
8
+
9
+ def initialize(path)
10
+ @raw = Hashie::Mash.new(YAML.load(File.read(path)))
11
+ validate!
12
+ end
13
+
14
+ def github_reponame
15
+ raw.github.owner + "/" + raw.github.repo
16
+ end
17
+
18
+ private
19
+ def validate!
20
+ # TODO
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,40 @@
1
+ require 'tenma/prepare/options'
2
+ require 'tenma/prepare/config'
3
+ require 'octokit'
4
+
5
+ module Tenma
6
+ module Prepare
7
+ class Context
8
+ attr_reader :options, :config, :client, :milestone, :release_manager
9
+
10
+ def load!(opts)
11
+ @options = Tenma::Prepare::Options.new(opts)
12
+ @config = Tenma::Prepare::Config.new(options.raw.config_file)
13
+ @client = load_github_client
14
+ @milestone = load_milestone!
15
+ @release_manager = load_release_manager!
16
+
17
+ self
18
+ end
19
+
20
+ private
21
+ def load_github_client
22
+ Octokit.configure do |c|
23
+ c.api_endpoint = config.raw.github.api_url
24
+ end
25
+ Octokit::Client.new(access_token: options.raw.github_token)
26
+ end
27
+
28
+ def load_milestone!
29
+ milestones = client.milestones(config.github_reponame, {state: "open"}).select do |milestone|
30
+ milestone[:title].include? options.raw.version
31
+ end
32
+ milestones.first or raise "Can't find a #{options.raw.version} milestone."
33
+ end
34
+
35
+ def load_release_manager!
36
+ client.user or raise "Can't find release manager."
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ require "erb"
2
+
3
+ module Tenma
4
+ module Prepare
5
+ class KptIssue
6
+ def initialize(context)
7
+ @context = context
8
+ end
9
+
10
+ def create
11
+ @context.client.create_issue(
12
+ @context.config.github_reponame,
13
+ formatted_title,
14
+ formatted_body,
15
+ {
16
+ labels: @context.config.raw.kpt_issue.labels,
17
+ assignee: @context.release_manager.login,
18
+ milestone: @context.milestone.number,
19
+ }
20
+ )
21
+ end
22
+
23
+ private
24
+ def formatted_title
25
+ ERB.new(@context.config.raw.kpt_issue.title).result(binding)
26
+ end
27
+
28
+ def formatted_body
29
+ ERB.new(@context.config.raw.kpt_issue.body).result(binding)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ require "hashie/mash"
2
+
3
+ module Tenma
4
+ module Prepare
5
+ class Options
6
+
7
+ attr_reader :raw
8
+ def initialize(opts)
9
+ @raw = Hashie::Mash.new(opts.map { |k, v| [k.gsub(/-/, "_"), v] }.to_h)
10
+ end
11
+
12
+ def create_kpt_issue?
13
+ return !!raw.kpt_issue
14
+ end
15
+
16
+ def create_release_issue?
17
+ return !!raw.release_issue
18
+ end
19
+
20
+ def create_release_branch?
21
+ return !!raw.release_branch
22
+ end
23
+
24
+ def create_release_pullreqs?
25
+ return !!raw.release_pullreqs
26
+ end
27
+
28
+ def hotfix?
29
+ raw.version.split(".")[2] != "0"
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,92 @@
1
+ require 'git'
2
+ require 'uri'
3
+ require 'erb'
4
+
5
+ module Tenma
6
+ module Prepare
7
+ class ReleaseBranch
8
+
9
+ TEMP_DIR = "tenma-build"
10
+
11
+ def initialize(context)
12
+ @context = context
13
+ end
14
+
15
+ def create
16
+ @workdir = Dir.mktmpdir
17
+ git = Git.clone(repo_url, TEMP_DIR, path: @workdir, depth: 1, branch: base_branch)
18
+
19
+ git.branch(release_branch).checkout
20
+
21
+ File.write(version_file, @context.options.raw.version)
22
+ git.add(version_file)
23
+
24
+ git.commit("version++")
25
+
26
+ changelogs = @context.config.raw.release_branch&.changelogs
27
+ changelogs&.each do |changelog|
28
+ file = create_changelog_file(changelog)
29
+ git.add(file)
30
+ git.commit("Add changelog to #{changelog.path}")
31
+ end
32
+ git.push(git.remote("origin"), release_branch)
33
+ end
34
+
35
+ def create_changelog_file(changelog)
36
+ FileUtils::mkdir_p(File.join(@workdir, TEMP_DIR, changelog.path))
37
+
38
+ file = changelog_file(changelog.path)
39
+ File.open(file, 'w') do |file|
40
+ file.puts changelog(changelog.body)
41
+ end
42
+
43
+ return file
44
+ end
45
+
46
+ def changelog(note)
47
+ return '' if note.nil?
48
+
49
+ ERB.new(note).result(binding)
50
+ end
51
+
52
+ private
53
+ def repo_url
54
+ base = URI.parse(@context.config.raw.github.web_url)
55
+ return base.scheme + "://" + @context.options.raw.github_token + ":x-oauth-basic@" + base.host + "/" + @context.config.github_reponame + ".git"
56
+ end
57
+
58
+ def base_branch
59
+ if @context.options.hotfix?
60
+ ERB.new(@context.config.raw.release_branch.hotfix.base).result(binding)
61
+ else
62
+ ERB.new(@context.config.raw.release_branch.normal.base).result(binding)
63
+ end
64
+ end
65
+
66
+ def version_file
67
+ File.absolute_path(File.join(@workdir, TEMP_DIR, @context.config.raw.release_branch.version_file))
68
+ end
69
+
70
+ def changelog_file(path)
71
+ file = parse_version.to_s + '.txt'
72
+ File.absolute_path(File.join(@workdir, TEMP_DIR, path, file))
73
+ end
74
+
75
+ def parse_version
76
+ version = @context.options.raw.version
77
+ major = version.split('.')[0].to_i
78
+ minor = version.split('.')[1].to_i
79
+ patch = version.split('.')[2].to_i
80
+ return major * 1000 * 1000 + minor * 1000 + patch
81
+ end
82
+
83
+ def release_branch
84
+ if @context.options.hotfix?
85
+ ERB.new(@context.config.raw.release_branch.hotfix.branch).result(binding)
86
+ else
87
+ ERB.new(@context.config.raw.release_branch.normal.branch).result(binding)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,33 @@
1
+ require "erb"
2
+
3
+ module Tenma
4
+ module Prepare
5
+ class ReleaseIssue
6
+ def initialize(context)
7
+ @context = context
8
+ end
9
+
10
+ def create
11
+ @context.client.create_issue(
12
+ @context.config.github_reponame,
13
+ formatted_title,
14
+ formatted_body,
15
+ {
16
+ labels: @context.config.raw.release_issue.labels,
17
+ assignee: @context.release_manager.login,
18
+ milestone: @context.milestone.number,
19
+ }
20
+ )
21
+ end
22
+
23
+ private
24
+ def formatted_title
25
+ ERB.new(@context.config.raw.release_issue.title).result(binding)
26
+ end
27
+
28
+ def formatted_body
29
+ ERB.new(@context.config.raw.release_issue.body).result(binding)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,48 @@
1
+ module Tenma
2
+ module Prepare
3
+ class ReleasePullreqs
4
+
5
+ def initialize(context)
6
+ @context = context
7
+ end
8
+
9
+ def create
10
+ @context.config.raw.release_pullreq.bases.each do |base_branch|
11
+ pullreq = @context.client.create_pull_request(
12
+ @context.config.github_reponame,
13
+ base_branch,
14
+ release_branch,
15
+ formatted_title(base_branch),
16
+ formatted_body(base_branch),
17
+ )
18
+
19
+ @context.client.update_issue(
20
+ @context.config.github_reponame,
21
+ pullreq.number,
22
+ labels: @context.config.raw.release_pullreq.labels,
23
+ assignee: @context.release_manager.login,
24
+ milestone: @context.milestone.number,
25
+ )
26
+ end
27
+ end
28
+
29
+ private
30
+ def release_branch
31
+ if @context.options.hotfix?
32
+ ERB.new(@context.config.raw.release_branch.hotfix.branch).result(binding)
33
+ else
34
+ ERB.new(@context.config.raw.release_branch.normal.branch).result(binding)
35
+ end
36
+ end
37
+
38
+ def formatted_title(base_branch)
39
+ ERB.new(@context.config.raw.release_pullreq.title).result(binding)
40
+ end
41
+
42
+ def formatted_body(base_branch)
43
+ ERB.new(@context.config.raw.release_pullreq.body).result(binding)
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ module Tenma
2
+ VERSION = "0.9.0"
3
+ end
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "tenma/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tenma"
8
+ spec.version = Tenma::VERSION
9
+ spec.authors = ["hisaichi5518"]
10
+ spec.email = ["hisaichi5518@gmail.com"]
11
+
12
+ spec.summary = %q{Tenma is command line tool for mobile application development.}
13
+ spec.description = %q{Tenma is command line tool for mobile application development.}
14
+ spec.homepage = "https://github.com/hisaichi5518/tenma"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_dependency 'thor'
25
+ spec.add_dependency 'octokit'
26
+ spec.add_dependency 'hashie'
27
+ spec.add_dependency 'git'
28
+ spec.add_dependency 'itamae'
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.15"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rspec", "~> 3.0"
33
+ end
metadata ADDED
@@ -0,0 +1,191 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tenma
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - hisaichi5518
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-04-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: octokit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: hashie
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: git
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: itamae
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.15'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.15'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '10.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '10.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ description: Tenma is command line tool for mobile application development.
126
+ email:
127
+ - hisaichi5518@gmail.com
128
+ executables:
129
+ - tenma
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - ".rspec"
135
+ - ".travis.yml"
136
+ - Gemfile
137
+ - LICENSE.txt
138
+ - README.md
139
+ - Rakefile
140
+ - bin/console
141
+ - bin/setup
142
+ - exe/tenma
143
+ - lib/tenma.rb
144
+ - lib/tenma/cli.rb
145
+ - lib/tenma/ichiba/command.rb
146
+ - lib/tenma/ichiba/context.rb
147
+ - lib/tenma/ichiba/instance.rb
148
+ - lib/tenma/ichiba/itamae/cookbooks/android-sdk/default.rb
149
+ - lib/tenma/ichiba/itamae/cookbooks/android-sdk/dependency.rb
150
+ - lib/tenma/ichiba/itamae/cookbooks/android-sdk/install.rb
151
+ - lib/tenma/ichiba/itamae/cookbooks/android-sdk/templates/install-android-sdk-components.sh.erb
152
+ - lib/tenma/ichiba/itamae/cookbooks/initialize/default.rb
153
+ - lib/tenma/ichiba/itamae/cookbooks/mainframer/default.rb
154
+ - lib/tenma/ichiba/itamae/roles/remote.rb
155
+ - lib/tenma/ichiba/options.rb
156
+ - lib/tenma/ichiba/validator.rb
157
+ - lib/tenma/prepare/command.rb
158
+ - lib/tenma/prepare/config.rb
159
+ - lib/tenma/prepare/context.rb
160
+ - lib/tenma/prepare/kpt_issue.rb
161
+ - lib/tenma/prepare/options.rb
162
+ - lib/tenma/prepare/release_branch.rb
163
+ - lib/tenma/prepare/release_issue.rb
164
+ - lib/tenma/prepare/release_pullreqs.rb
165
+ - lib/tenma/version.rb
166
+ - tenma.gemspec
167
+ homepage: https://github.com/hisaichi5518/tenma
168
+ licenses:
169
+ - MIT
170
+ metadata: {}
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubyforge_project:
187
+ rubygems_version: 2.6.11
188
+ signing_key:
189
+ specification_version: 4
190
+ summary: Tenma is command line tool for mobile application development.
191
+ test_files: []