Build and Release

A continuous learner for experience and life.

加入 Apple iOS 开发者计划

起步

学习开发 iOS 应用程序的第一步是理解注册为 Apple 开发者和 iOS 开发者计划会员的不同。然后决定你在什么时候付费加入 iOS 开发者计划。本章就来谈论一下 Apple 开发者和 iOS 开发者计划的差别,大概需要的费用以及加入开发者计划的好处。最后,一步步告诉大家怎么样加入这些计划成为会员。

注册成为 Apple 开发者

注册成为 Apple 开发者不需要费用,很简单,访问以下链接:

http://developer.apple.com/programs/register/

然后按照要求一步步开始注册。 使用 Apple ID 进行注册,这个 Apple ID 就是用来在 iTunes 或者 Apple Store 上面购买商品的账号。 完成这个注册,就可以获得一些开发者资源,例如在线文档,教程等等。开发者也能够下载旧版的 iOS 开发包(SDK),以及 Xcode 开发环境(IDE)。

Playing With Gerrit Jira Plugin

Gerrit

Build and Setup

1. Clone the Gerrit source:

1
$ git clone https://gerrit.googlesource.com/gerrit

2. Checkout to version 2.8 (2.8 is the latest stable version), include to update submodules:

1
2
3
$ cd gerrit
$ git checkout -b stable-2.8 stable-2.8
$ git submodule update --init --rebase # commands, please referece to git submodule

3. Clone buck, buck is the build system for the latest Gerrit, then build it with ant (‘sudo apt-get install ant’):

1
2
3
$ git clone https://gerrit.googlesource.com/buck
$ cd buck
$ ant

4. Install buck to be accessed globally:

1
2
3
4
5
$ mkdir ~/bin
$ export PATH=~/bin:$PATH
$ ln -s `pwd`/bin/buck ~/bin/
$ ln -s `pwd`/bin/buckd ~/bin/
$ which buck

5. Build Gerrit:

1
2
$ cd gerrit
$ buck build gerrit

NOTE: The gerrit.war will be generated here: buck-out/gen/gerrit.war

6. Build extension, plugin, GWT API jar files, and install them:

1
2
$ buck build api
$ buck build api_install

7. Build all core plugins (optional):

1
$ buck build plugins:core

NOTE: All core plugins will be generated here: buck-out/gen/plugins/<name>/<name>.jar

8. Clone the hooks-its, and hooks-jira projects:

1
2
3
4
5
$ git clone https://gerrit.googlesource.com/plugins/hooks-its plugins/hooks-its
$ cd plugins/hooks-its
$ git checkout -b v2.8 origin/stable-2.8
$ cd ../..
$ git clone https://gerrit.googlesource.com/plugins/hooks-jira plugins/hooks-jira

9. Modify the pom.xml files under plugins/hooks-its AND plugins/hooks-its/hooks-its:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
cd plugins/hooks-its
$ git diff
diff --git a/hooks-its/pom.xml b/hooks-its/pom.xml
index a206459..75e11dc 100644
--- a/hooks-its/pom.xml
+++ b/hooks-its/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
   <parent>
     <groupId>com.googlesource.gerrit.plugins.its</groupId>
     <artifactId>hooks-its-parent</artifactId>
-    <version>2.9-SNAPSHOT</version>
+    <version>2.8</version>
   </parent>
   <artifactId>hooks-its</artifactId>
   <name>Gerrit Code Review - Commit validation and Workflow</name>
diff --git a/pom.xml b/pom.xml
index 600bff9..995d008 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@ limitations under the License.
   <groupId>com.googlesource.gerrit.plugins.its</groupId>
   <artifactId>hooks-its-parent</artifactId>
   <packaging>pom</packaging>
-  <version>2.9-SNAPSHOT</version>
+  <version>2.8</version>

   <name>Gerrit Code Review - Issue tracker support</name>

10. Build the hooks-its:

1
2
$ cd plugins/hooks-its
$ mvn -DskipTests -Dmaven.test.skip=true package install

NOTE: The hooks-its-2.8.jar will be generated here: hooks-its/target/hooks-its-2.8.jar NOTE: If don’t skip tests, run with the command: mvn clean package install, then will fail on test case! NOTE: Gerrit select BUCK as its new build system, for new plugin, please reference to the following NOTES #5

11. Modify the pom.xml files under plugins/hooks-jira:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cd plugins/hooks-jira
$ git diff
diff --git a/pom.xml b/pom.xml
index 7b04c60..8f60c78 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@ limitations under the License.
   <parent>
     <groupId>com.googlesource.gerrit.plugins.its</groupId>
     <artifactId>hooks-its-parent</artifactId>
-    <version>2.9-SNAPSHOT</version>
+    <version>2.8</version>
   </parent>
   <artifactId>hooks-jira</artifactId>
   <packaging>jar</packaging>

12. Build the hooks-jira:

1
2
$ cd plugins/hooks-jira
$ mvn clean package

NOTE: The hooks-jira-2.8.jar will be generated here: target/hooks-jira-2.8.jar

13. Copy the following jar files to the plugin folder under the Gerrit installation path on remote server:

1
2
hooks-its-2.8.jar
hooks-jira-2.8.jar

For example:

1
$ scp hooks-its/target/hooks-its-2.8.jar ../hooks-jira/target/hooks-jira-2.8.jar gerrit2@review.example.co:/home/gerrit2/review_site/plugins

14. Add a new file etc/its/action.config under the Gerrit installation path on remote server:

1
2
3
4
5
6
7
8
9
10
11
12
[rule "merged"]
        event-type = change-merged
        action = add-standard-comment
[rule "comment"]
        event-type = comment-added
        action = add-standard-comment
[rule "patch-set"]
        event-type = patchset-created
        action = add-standard-comment
[rule "ref-updated"]
        event-type = ref-updated
        action = add-standard-comment

15. Run the Gerrit initial installation command on remote server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
$ java -jar gerrit-2.8.war init -d review_site

*** Gerrit Code Review 2.8
***


*** Git Repositories
***

Location of Git repositories   [git]:

*** SQL Database
***

Database server type           [mysql]:
Server hostname                [localhost]:
Server port                    [(mysql default)]:
Database name                  [reviewdb]:
Database username              [gerrit2]:
Change gerrit2's password      [y/N]?

*** User Authentication
***

Authentication method          [DEVELOPMENT_BECOME_ANY_ACCOUNT/?]:

*** Email Delivery
***

SMTP server hostname           [localhost]:
SMTP server port               [(default)]:
SMTP encryption                [NONE/?]:
SMTP username                  [gerrit2]:
Change gerrit2's password      [y/N]?

*** Container Process
***

Run as                         [gerrit2]:
Java runtime                   [C:\Program Files (x86)\Java\jre7]:
Upgrade c:\Users\gerrit2\gerrit\bin\gerrit.war [Y/n]?
Copying gerrit-2.8.war to c:\Users\gerrit2\gerrit\bin\gerrit.war

*** SSH Daemon
***

Listen on address              [*]:
Listen on port                 [29418]:

*** HTTP Daemon
***

Behind reverse proxy           [y/N]?
Use SSL (https://)             [y/N]?
Listen on address              [*]:
Listen on port                 [8080]:
Canonical URL                  [http://review.example.com:8080/]:

*** Plugins
***

Install plugin reviewnotes version v2.8 [y/N]?
Install plugin download-commands version v2.8 [y/N]?
Install plugin replication version v2.8 [y/N]?
Install plugin commit-message-length-validator version v2.8 [y/N]?


*** Jira connectivity
***

Jira URL (empty to skip)       [https://jira.example.com/]:
Jira username                  [jira-robot]:
Change jira-robot's password        [y/N]?
Test connectivity to https://jira.example.com [y/N]? y
Checking Jira connectivity ... [OK]

*** Jira issue-tracking association
***

Jira issue-Id regex            [([A-Z]+-[0-9]+)]:
Issue-id enforced in commit message [MANDATORY/?]:?
Supported options are:
           mandatory
           suggested
           optional
Issue-id enforced in commit message [MANDATORY/?]: suggested
Initialized C:\Users\gerrit2\gerrit

16. Restart gerrit-jetty service:

1
$ sudo service gerrit-jetty.sh restart

17. Done!

NOTES:

1. Download Gerrit here: http://gerrit-releases.storage.googleapis.com/index.html

2. The file review_site/etc/gerrit.config should look like:

1
2
3
4
5
6
7
8
[jira]
        url = http://review.example.com:8080
        username = jira-robot
        commentOnRefUpdatedGitWeb = false   # to comment gitweb comments on jira
[commentLink "jira"]
        match = ([A-Z]+-[0-9]+)
        html = <a href=\"http://jira.example.com:8080/browse/$1\">$1</a>
        association = SUGGESTED

3. If we just want to parse the jira id on the subject of the git comments, then here is the diff:

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/util/
index a04b175..3d56426 100644
--- a/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/util/CommitM
+++ b/hooks-its/src/main/java/com/googlesource/gerrit/plugins/hooks/util/CommitM
@@ -31,7 +31,7 @@ public class CommitMessageFetcher {
       RevWalk revWalk = new RevWalk(repo);
       RevCommit commit = revWalk.parseCommit(ObjectId.fromString(commitId));

-      return commit.getFullMessage();
+      return commit.getShortMessage();
     } finally {
       repo.close();
     }

4. Get the log message from jetty/logs on Gerrit server. 5. Gerrit choose BUCK as its new build system, so for the new plugin, the build steps should be (take cookbook-plugin as an example):

1
buck build plugins/cookbook-plugin

The output is created in: buck-out/gen/plugins/cookbook-plugin/cookbook-plugin.jar

References:

1. https://groups.google.com/forum/#!msg/repo-discuss/GSyHMeaCyyw/cJGunFcNc4oJ 2. https://gerrit-review.googlesource.com/Documentation/dev-buck.html

Written with StackEdit.

Playing With Jenkins Create Job

Jenkins logo

create new job from templates

In this article, we will talk about how to create a Jenkins job with a template by some commands.

Instructions

1. Get the Jenkins CLI client package

1
$ wget http://jenkins/jnlpJars/jenkins-cli.jar

2. Check which commands supported by the client package [Exception 1,2]

1
$ java -jar jenkins-cli.jar -s http://jenkins/ help

3. List all jobs under the view: tools

1
$ java -jar jenkins-cli.jar -s http://jenkins/ list-jobs tools

4. Get the configuration of the job: template

1
$ java -jar jenkins-cli.jar -s http://jenkins/ get-job template > template.xml

5. Create a new job based on the configuration

1
$ java -jar jenkins-cli.jar -s http://jenkins/ create-job new_job_name < new_job_name.xml

6. Run groovy script

1
$ java -jar jenkins-cli.jar -s http://jenkins/ groovy scripts/add_job_to_view.groovy

If there are any parameters in the script, just as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import jenkins.model.*

if (args.length != 2 ) {
  println "Error on arguments!"
}
def jobName  = args[0] ?: 'a_job'
def viewName = args[1] ?: 'a_view'

println jobName + ' ' + viewName

def v = Jenkins.instance.getView(viewName)
def i = Jenkins.instance.getItemByFullName(jobName)
if (v && i) {
  v.add(i)
}

pass the parameters as:

1
$ java -jar jenkins-cli.jar -s http://jenkins/ groovy scripts/add_job_to_view.groovy JOB_NAME VIEM_NAME

7. Build a job

1
$ java -jar jenkins-cli.jar -s http://jenkins/ build new_job_name

8. Diable a job

1
$ java -jar jenkins-cli.jar -s http://jenkins/ disable-job new_job_name

Exceptions:

1. Description:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Exception in thread "main" java.io.IOException: No X-Jenkins-CLI2-Port among [null, Vary, Date, Content-Length, Keep-Alive, Set-Cookie, Connection, Content-Type, X-Powered-By, Server]
  at hudson.cli.CLI.getCliTcpPort(CLI.java:281)
  at hudson.cli.CLI.<init>(CLI.java:128)
  at hudson.cli.CLIConnectionFactory.connect(CLIConnectionFactory.java:72)
  at hudson.cli.CLI._main(CLI.java:449)
  at hudson.cli.CLI.main(CLI.java:378)
  Suppressed: java.io.EOFException: unexpected stream termination
      at hudson.remoting.ClassicCommandTransport.create(ClassicCommandTransport.java:100)
      at hudson.remoting.Channel.<init>(Channel.java:392)
      at hudson.remoting.Channel.<init>(Channel.java:388)
      at hudson.remoting.Channel.<init>(Channel.java:349)
      at hudson.remoting.Channel.<init>(Channel.java:345)
      at hudson.remoting.Channel.<init>(Channel.java:333)
      at hudson.cli.CLI.connectViaHttp(CLI.java:159)
      at hudson.cli.CLI.<init>(CLI.java:132)
      ... 3 more

Solution: check the port which Jenkins is running on, put 8080 on URL should fix, just as:

1
$ java -jar jenkins-cli.jar -s http://jenkins:8080/ help

2. Description:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Failed to authenticate with your SSH keys.
hudson.security.AccessDeniedException2: anonymous is missing the ExtendedRead permission
  at hudson.security.ACL.checkPermission(ACL.java:54)
  at hudson.model.AbstractItem.checkPermission(AbstractItem.java:441)
  at hudson.cli.GetJobCommand.run(GetJobCommand.java:46)
  at hudson.cli.CLICommand.main(CLICommand.java:229)
  at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:92)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:616)
  at hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:275)
  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:256)
  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:215)
  at hudson.remoting.UserRequest.perform(UserRequest.java:118)
  at hudson.remoting.UserRequest.perform(UserRequest.java:48)
  at hudson.remoting.Request$2.run(Request.java:326)
  at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
  at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:63)
  at hudson.remoting.InterceptingExecutorService$2.call(InterceptingExecutorService.java:95)
  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
  at java.util.concurrent.FutureTask.run(FutureTask.java:166)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
  at java.lang.Thread.run(Thread.java:679)

Solution: add client public ssh key to the Jenkins server at: http://jenkins/user/USERNAME/configure | SSH Public Keys.

3. Description:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
hudson.security.AccessDeniedException2: <USERNAME> is missing the Job/ExtendedRead permission
  at hudson.security.ACL.checkPermission(ACL.java:54)
  at hudson.model.AbstractItem.checkPermission(AbstractItem.java:446)
  at hudson.cli.GetJobCommand.run(GetJobCommand.java:46)
  at hudson.cli.CLICommand.main(CLICommand.java:234)
  at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:92)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:606)
  at hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:300)
  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:281)
  at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:240)
  at hudson.remoting.UserRequest.perform(UserRequest.java:118)
  at hudson.remoting.UserRequest.perform(UserRequest.java:48)
  at hudson.remoting.Request$2.run(Request.java:328)
  at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
  at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:63)
  at hudson.remoting.InterceptingExecutorService$2.call(InterceptingExecutorService.java:95)
  at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
  at java.util.concurrent.FutureTask.run(FutureTask.java:262)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  at java.lang.Thread.run(Thread.java:745)

Solution: Jenkins server –> Manage Jenkins –> Configure Global Security to add related permissions.

References:

  1. http://www.blackpepper.co.uk/generating-new-jenkins-jobs-from-templates-and-parameterised-builds/
  2. http://javadoc.jenkins-ci.org/jenkins/model/Jenkins.html
  3. https://github.com/jenkinsci/jenkins

Written with StackEdit.

Playing With Git Submodule

enter image description here

Intructions:

  • add a submodule
1
2
$ git submodule add -b BRANCH ssh://REPO_URL/REPO_PATH SUBMODULE_PATH
$ git commit -m "add a submodule at SUBMODULE_PATH"
  • clone the project with submodule(s)
1
2
3
$ git clone ssh://REPO_URL/REPO_PATH PROJECT
cd PROJECT
$ git submodule update --init --rebase
  • get submodule status
1
2
$ git submodule status
$ git submodule foreach git branch -a
  • checkout all submodule to a branch defined in .gitmodule (which means we specify the branch when we add the submodule with ‘-b BRANCH’)
1
2
3
$ git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git checkout $branch'
# OR a short version
$ git submodule foreach git checkout master
  • pull the latest master for all of the submodule
1
$ git submodule -q foreach git pull -q origin master
  • develop in submodule
1
2
3
4
5
# Make your changes in submoduleA
$ cd submoduleA
$ git add .
$ git commit -m "Updated the submoduleA"
$ git push origin BRANCH
  • sync to project
1
2
3
$ cd PROJECT
$ git pull
$ git submodule update --rebase
  • manually update the project to track submodule (Gerrit submodule description commit the track automatically)
1
2
3
4
$ cd PROJECT
$ git add submoduleA
$ git commit -m "Updated submodule a."
$ git push origin BRANCH_NAME
  • deinit, and remove a submodule
1
2
3
$ git submodule deinit SUBMODULE_PATH
$ git rm SUBMODULE_PATH
$ git commit -m "remove the submodule at SUBMODULE_PATH"

References:

  1. http://git-scm.com/docs/git-submodule
  2. http://git-scm.com/docs/git-rm.html
  3. http://stackoverflow.com/questions/8642668/how-to-make-submodule-with-detached-head-to-be-attached-to-actual-head
  4. http://www.vogella.com/tutorials/Git/article.html#submodules

Written with StackEdit.

Rename Repository on Gerrit

Gerrit icon

Instructions:

1. Move the repository folder on server:

1
2
3
# on gerrit server
$ cd $site_path/git;
$ mv old_name.git new_name.git

2. Flush the caches on server:

1
2
# On another client image:
$ ssh -p 29418 gerrit.server.com gerrit flush-caches

3. Run sql statement to update the changes:

1
2
3
4
5
6
7
8
# On another client image (need "Access Database" capability):
$ ssh -p 29418 gerrit.server.com gerrit gsql [Enter]
gerrit> USE {Database};
gerrit> SELECT * FROM changes WHERE dest_project_name = 'old_name';
# if have more than 1, run the following command to update, otherwise, quit with \q;
gerrit> UPDATE changes SET dest_project_name = 'new_name' WHERE
dest_project_name = 'old_name';
gerrit> \q

References:

  1. https://groups.google.com/forum/#!topic/repo-discuss/ltIxBipUPKI

Written with StackEdit.

Migrate Svn to Git

migrate svn to git

Instructions:

1. Check out the source tree from SVN server with svn command:

1
svn co http://my-project.googlecode.com/svn/trunk

2. Generate an users.txt with the command:

1
2
$ svn log ^/ --xml | grep -P "^<author" | sort -u | \
      perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt

and following the formatting:

1
2
schacon = Scott Chacon <schacon@geemail.com>
selse = Someo Nelse <selse@geemail.com>

NOTE: You can try the script to generate authors list automatically: https://gist.github.com/lifuzu/9081923#file-findauthors-sh

3. Once the users.txt is ready, then checkout the source tree again with the command ‘git svn clone’:

1
2
$ git svn clone http://my-project.googlecode.com/svn/ \
      --authors-file=users.txt --no-metadata -s my_project

4. To move the tags to be proper Git tags, run:

1
$ git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done

5. To move the rest of the references under refs/remotes to be local branches:

1
$ git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done

6. Adding the git server as a remote:

1
$ git remote add origin git@my-git-server:myrepository.git

7. Push all your branches and tags to go up:

1
2
$ git push origin --all
$ git push origin --tags

8. Update the changes from SVN (before you update, please cleanup your local workspace)

1
2
3
4
5
$ git svn fetch
...
r81152 = c2465633b56d16081334336ee87d506b97d10449 (refs/remotes/git-svn)
$ git checkout master
$ git merge remotes/git-svn

NOTE: Sometimes when you run git svn fetch:

1
2
...
r81217 = eb79c770f852f6158a583bb17a8c1a326f7b4e03 (refs/remotes/trunk)

Then you need to run:

1
2
$ git checkout master
$ git merge remotes/trunk

9. Then check them into GIT

1
2
$ git log # should have some changes merged from SVN
$ git push origin master

10. If you have a temporary migration branch you modified something on that, then you need rebase the changes on master to migration:

1
2
$ git checkout migration
$ git rebase master  # fix the conflicts if have

11. Finally, you need merge the changes on migration, fast forward, since you have rebased.

1
2
$ git checkout master
$ git merge migration

That is it!

Reference:

  1. http://git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git
  2. http://git-scm.com/book/ch3-6.html
  3. http://stackoverflow.com/questions/16565991/keep-svn-repository-in-sync-with-git-one
  4. http://stackoverflow.com/questions/5241898/is-a-bidrectional-git-svn-sync-both-writable-possible

Written with StackEdit.

Raft - Distributed Consensus Protocol

Rafe is a distributed consensus protocol, which allows a collection of processes to maintain consistency even in the face of multiple node failure. The two main tenants of the protocol are leader election and log replication.

产品设计冲刺:为期五天的创业配方

原文地址:http://www.designstaff.org/articles/product-design-sprint-2012-10-02.html

在谷歌风险投资公司,我们每天都与创业公司做产品设计工作。由于我们行动迅速 ,他们也希望能迅速行动,我们优化了一些过程,可以让我们在五天以内见到良好的效果。我们把它叫做一个产品设计的冲刺,这个相当不错,它可以让你不再抓狂并加速已经进行中的项目。

我已经策划并运行了40几个这样的冲刺,先是在谷歌内部的团队,现在在谷歌风险投资公司投资的一些初创公司。给你一个直观的样子,这里是我们与CustomMade做了一个项目:

产品设计Sprint

原文地址:http://robots.thoughtbot.com/the-product-design-sprint

产品设计Sprint是一个5个阶段的演习,使用设计思维,减少内在风险,把产品成功推向市场。到目前为止,我们已经做了六大产品的设计Sprint,并使得他们成为我们咨询活动预设的一部分。

参加一个以设计Sprint为定向的团队,旨在努力达成明确清晰的目标。开始一个新的功能,工作流程,产品,业务或解决一个现有产品的问题,Sprint都是有用的出发点。

集设计Sprint和设计思想到我们的产品开发过程中,使我们与我们的目标保持一致,并帮助我们明智地投资我们的时间和金钱。

设计思想

设计思想结合换位思考,创造力和理性来解决以人为本的问题。它是设计Sprint建立的基础。

换位思考

有了设计思想,我们用换位思考的方法,通过我们客户的眼睛看世界,了解他们碰到的问题。这些问题可能涉及到技术,金融,政治,宗教,人,社会和文化等等。我们的工作就是要全面地理解这些问题,在一个更适用的环境下,开发出一套强化的、脉络清晰的架构。

除了从我们自己的角度,我们的目标是尽可能多地理解其他人的观点,以更好地使我们的理解多元化。

换位思考是第1阶段(理解)的首要重点和第5阶段(测试和学习)的主要部分。我们的目标应该是为人类解决问题和制造产品,要始终保持换位思考。

创造力

创意是机会的发现。我们运用创造力来产生洞察力和解决方案的概念。

最有创意的解决方案是由独到的见解和交叉的视角启发的。换位思考,如上所述,让我们具有理解不同的观点和更具创造性的能力。

合作激发创造力。更多的观点,想法和见解导致更多的机会。

创意是第2阶段(发散)的焦点,但存在于所有阶段(开发原型,测试/面试,研究/观察,创造实验等)

理性

我们使用理性,通过实验,测试和定性/定量的测量,以找到适应问题背景的解决方案。这是第3阶段(汇流)和第5阶段(测试和学习)的主要焦点。

设计思想也应该渗透我们所有的设计Sprint过程中,从工程设计到营销到业务发展。在复杂的商业生态系统中,设计思想可以作为一种全面的方法来促进和维护与客户的共生关系。