Skip to content

Commit

Permalink
feat(yolo): Add android release
Browse files Browse the repository at this point in the history
  • Loading branch information
gfanton committed Dec 11, 2018
1 parent b9d0d61 commit 870ce75
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 12 deletions.
73 changes: 63 additions & 10 deletions server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ import (
)

const (
BUNDLE_ID = "chat.berty.ios"
APP_NAME = "berty"
JOB_IOS = "client.rn.ios"
BUNDLE_ID = "chat.berty.ios"
APP_NAME = "berty"
IOS_JOB = "client.rn.ios"
ANDROID_JOB = "client.rn.android"
)

var reIPA = regexp.MustCompile("/([^/]+).ipa$")
var reAPK = regexp.MustCompile("/([^/]+).apk$")
var reVersion = regexp.MustCompile("/version$")

func (s *Server) Build(c echo.Context) error {
Expand Down Expand Up @@ -106,6 +108,30 @@ func (s *Server) GetIPA(c echo.Context) error {
return echo.NewHTTPError(http.StatusInternalServerError, "IPA not found")
}

func (s *Server) GetAPK(c echo.Context) error {
id := c.Param("*")
arts, err := s.client.GetArtifacts(id, true)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

for _, art := range arts {
if !reAPK.MatchString(art.PrettyPath) {
continue
}

// Download client
rc, err := s.client.GetArtifact(art)
if err != nil {
return err
}

return c.Stream(http.StatusOK, "application/vnd.android.package-archive", rc)
}

return echo.NewHTTPError(http.StatusInternalServerError, "APK not found")
}

var masterMerge = regexp.MustCompile(`^Merge pull request #([0-9]+) from (.*)$`)

func (s *Server) ListReleaseIOSJson(c echo.Context) error {
Expand Down Expand Up @@ -141,7 +167,7 @@ func (s *Server) ListReleaseIOSJson(c echo.Context) error {
}
}
for _, build := range s.cache.builds.Sorted() {
if build.BuildParameters["CIRCLE_JOB"] != "client.rn.ios" {
if build.BuildParameters["CIRCLE_JOB"] != IOS_JOB {
continue
}
if _, found := oncePerBranch[build.Branch]; found {
Expand All @@ -165,7 +191,15 @@ func (s *Server) ListReleaseIOSJson(c echo.Context) error {
return c.JSON(http.StatusOK, ret)
}

func (s *Server) ListReleaseAndroid(c echo.Context) error {
return s.ListRelease(c, ANDROID_JOB)
}

func (s *Server) ListReleaseIOS(c echo.Context) error {
return s.ListRelease(c, IOS_JOB)
}

func (s *Server) ListRelease(c echo.Context, job string) error {
html := `<html><head><link rel="stylesheet" href="/assets/site.css">` + faviconHTMLHeader + `</head><body><div class="container">`

dlIcon := `<svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>`
Expand All @@ -174,7 +208,7 @@ func (s *Server) ListReleaseIOS(c echo.Context) error {
previousDate := ""
now := time.Now().Truncate(time.Hour * 24)
for _, build := range s.cache.builds.Sorted() {
if build.BuildParameters["CIRCLE_JOB"] != "client.rn.ios" {
if job != build.BuildParameters["CIRCLE_JOB"] {
continue
}
if _, found := oncePerBranch[build.Branch]; found && build.Branch != "master" {
Expand All @@ -189,7 +223,13 @@ func (s *Server) ListReleaseIOS(c echo.Context) error {
updateTime = build.StopTime
}

currentDate := updateTime.Format("2006/01/02")
var currentDate string
if updateTime != nil {
currentDate = updateTime.Format("2006/01/02")
} else {
currentDate = "n/a"
}

stopDay := updateTime.Truncate(time.Hour * 24)
dayDiff := math.Ceil(stopDay.Sub(now).Hours() / 24)
if dayDiff != 0 {
Expand Down Expand Up @@ -224,7 +264,7 @@ func (s *Server) ListReleaseIOS(c echo.Context) error {
if build.StopTime != nil {
prBranch = fmt.Sprintf("build/%d", build.BuildNum)
}
token := s.getHash(prBranch)

if subject == "" {
subject = "n/a"
}
Expand Down Expand Up @@ -265,11 +305,24 @@ func (s *Server) ListReleaseIOS(c echo.Context) error {
buildLink := fmt.Sprintf(`<a href="%s">%d</a>`, build.BuildURL, build.BuildNum)
age := durafmt.ParseShort(time.Since(*updateTime))

var href string
switch job {
case IOS_JOB:
iosToken := s.getHash(prBranch)
href = fmt.Sprintf(`itms-services://?action=download-manifest&url=https://%s/auth/itms/release/%s/%s`, s.hostname, iosToken, prBranch)
case ANDROID_JOB:
id := strconv.Itoa(build.BuildNum)
androidToken := s.getHash(id)
href = fmt.Sprintf(`https://%s/auth/apk/build/%s/%s`, s.hostname, androidToken, id)
default:
return echo.NewHTTPError(http.StatusInternalServerError, "unknow job")
}

elems := []string{
fmt.Sprintf(`<div class="b-head">%s&nbsp;&nbsp;%s</div>`, branchLink, build.User.Login),
fmt.Sprintf(`<div class="b-body"><div class="b-left"><div class="b-build">%s&nbsp;&nbsp;%s<br />%s&nbsp;&nbsp;%s&nbsp;&nbsp;%s</div></div>`, commitLink, subject, buildLink, age, duration),
fmt.Sprintf(`<div class="b-right"><div class="b-diff">%s</div>`, diff),
fmt.Sprintf(`<div class="b-download"><a class="btn" href="itms-services://?action=download-manifest&url=https://%s/auth/itms/release/%s/%[3]s">%s</a></div></div></div>`, s.hostname, token, prBranch, dlIcon),
fmt.Sprintf(`<div class="b-download"><a class="btn" href="%s">%s</a></div></div></div>`, href, dlIcon),
// FIXME: create a link /auth/itms/release/TOKEN/ID instead of /auth/itms/release/TOKEN/BRANCH (this way we can handle multiple artifacts per branch)
}

Expand All @@ -281,7 +334,7 @@ func (s *Server) ListReleaseIOS(c echo.Context) error {

func (s *Server) ReleaseIOS(c echo.Context) error {
pull := c.Param("*")
builds, err := s.client.Builds(pull, JOB_IOS, 100, 0)
builds, err := s.client.Builds(pull, IOS_JOB, 100, 0)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
Expand Down Expand Up @@ -320,7 +373,7 @@ func (s *Server) Itms(c echo.Context) error {
}
*/
if theBuild == nil {
builds, err := s.client.Builds(pull, JOB_IOS, 100, 0)
builds, err := s.client.Builds(pull, IOS_JOB, 100, 0)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
Expand Down
17 changes: 15 additions & 2 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import (
"github.com/labstack/echo/middleware"
)

var reAndroidAgent = regexp.MustCompile("(?i)android")
var reIOSAgent = regexp.MustCompile("(?i)iPad|iPhone|iPod")

type httperror struct {
message string `json:message`
}
Expand Down Expand Up @@ -100,23 +103,33 @@ func NewServer(cfg *ServerConfig) *Server {

e.File("/favicon.ico", "assets/favicon.ico")
e.Static("/assets", "assets")

e.GET("/release/ios/*", s.ReleaseIOS)
e.GET("/release/ios", s.ListReleaseIOS)
e.GET("/release/android", s.ListReleaseAndroid)
e.GET("/", func(c echo.Context) error {
// FIXME: conditional depending on the user agent (android || ios)
header := c.Request().Header
if agent := header.Get("User-Agent"); agent != "" {
fmt.Println(agent)
if reAndroidAgent.MatchString(agent) {
return c.Redirect(http.StatusTemporaryRedirect, "/release/android")
}
}

return c.Redirect(http.StatusTemporaryRedirect, "/release/ios")
})
e.GET("/release/ios.json", s.ListReleaseIOSJson)

auth := e.Group("/auth")
if cfg.Password != "" {
excludeToken := regexp.MustCompile("^/auth/ipa/build/.+$|^/auth/itms/release/.+$")
excludeToken := regexp.MustCompile("^/auth/ipa/build/.+$|^/auth/apk/build/.+$|^/auth/itms/release/.+$")
auth.Use((s.basicAuth(cfg.Username, cfg.Password, excludeToken)))
}
auth.GET("/build/:build_id", s.Build)
auth.GET("/builds/*", s.Builds)
auth.GET("/artifacts/:build_id", s.Artifacts)
auth.GET("/ipa/build/:token/*", s.GetIPA)
auth.GET("/apk/build/:token/*", s.GetAPK)
auth.GET("/itms/release/:token/*", s.Itms)

return s
Expand Down

0 comments on commit 870ce75

Please sign in to comment.