diff --git a/app/src/main/res/raw/app_version_json.json b/app/src/main/res/raw/app_version_json.json index b980602..ea9d0cc 100644 --- a/app/src/main/res/raw/app_version_json.json +++ b/app/src/main/res/raw/app_version_json.json @@ -1,5 +1,5 @@ { "latest_version": "3.6.2-01", "changelog": "UPDATE: Update to 3.6.52", - "apk_url": "https://cloud.kain.id.vn/seafhttp/f/7a7d79a5354e4d39976f/?op=view" + "apk_url": "https://git.kain.io.vn/Firefly-Shelter/FireflyGo_Android/releases/download/3.6.2-01/firefly_go_android.apk" } \ No newline at end of file diff --git a/script/.gitignore b/script/.gitignore new file mode 100644 index 0000000..1b37fe0 --- /dev/null +++ b/script/.gitignore @@ -0,0 +1,2 @@ +.env +*.exe \ No newline at end of file diff --git a/script/README_Note.md b/script/README_Note.md new file mode 100644 index 0000000..5b72429 --- /dev/null +++ b/script/README_Note.md @@ -0,0 +1,2 @@ +# Changelog +UPDATE: Update to 3.6.52 \ No newline at end of file diff --git a/script/go.mod b/script/go.mod new file mode 100644 index 0000000..8318fee --- /dev/null +++ b/script/go.mod @@ -0,0 +1,5 @@ +module release + +go 1.25.0 + +require github.com/joho/godotenv v1.5.1 diff --git a/script/go.sum b/script/go.sum new file mode 100644 index 0000000..d61b19e --- /dev/null +++ b/script/go.sum @@ -0,0 +1,2 @@ +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= diff --git a/script/main.go b/script/main.go new file mode 100644 index 0000000..21a564c --- /dev/null +++ b/script/main.go @@ -0,0 +1,154 @@ +package main + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "mime/multipart" + "net/http" + "os" + "path/filepath" + "github.com/joho/godotenv" +) + +const ( + repoOwner = "Firefly-Shelter" + repoName = "FireflyGo_Android" + giteaURL = "https://git.kain.io.vn" +) + +type ReleaseInput struct { + TagName string `json:"tag_name"` + Name string `json:"name"` + Body string `json:"body"` + Draft bool `json:"draft"` + Prerelease bool `json:"prerelease"` +} + +type ReleaseResponse struct { + ID int `json:"id"` + HTMLURL string `json:"html_url"` + URL string `json:"url"` +} + +func readFile(path string) string { + data, err := os.ReadFile(path) + if err != nil { + panic(fmt.Sprintf("Failed to read %s: %v", path, err)) + } + return string(data) +} + +func main() { + err := godotenv.Load("script/.env") + if err != nil { + fmt.Println("Error loading .env file") + } + + token := os.Getenv("TOKEN") + if token == "" { + fmt.Println("TOKEN not found in .env") + } + + + releaseJSON := readFile("script/release.json") + var meta map[string]string + if err := json.Unmarshal([]byte(releaseJSON), &meta); err != nil { + panic("Invalid release.json") + } + tag := meta["tag"] + title := meta["title"] + body := readFile("script/README_Note.md") + + // Step 1: Create release + releaseInput := ReleaseInput{ + TagName: tag, + Name: title, + Body: body, + Draft: false, + Prerelease: false, + } + payload, _ := json.Marshal(releaseInput) + + req, _ := http.NewRequest("POST", + fmt.Sprintf("%s/api/v1/repos/%s/%s/releases", giteaURL, repoOwner, repoName), + bytes.NewReader(payload), + ) + req.Header.Set("Authorization", "token "+token) + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusCreated { + bodyBytes, _ := io.ReadAll(resp.Body) + panic(fmt.Sprintf("Failed to create release: %s", bodyBytes)) + } + + var releaseResp ReleaseResponse + if err := json.NewDecoder(resp.Body).Decode(&releaseResp); err != nil { + panic("Failed to decode release response") + } + + fmt.Printf("Release created:\n- ID: %d\n- HTML: %s\n", releaseResp.ID, releaseResp.HTMLURL) + + uploadURL := releaseResp.URL + if uploadURL == "" { + panic("url missing in release response") + } + + files, err := os.ReadDir("app/release") + if err != nil { + panic("Cannot read prebuild folder") + } + + for _, file := range files { + if filepath.Ext(file.Name()) != ".apk" { + continue + } + uploadPath := filepath.Join("app/release", file.Name()) + fmt.Println("Uploading:", uploadPath) + + buf := new(bytes.Buffer) + writer := multipart.NewWriter(buf) + part, err := writer.CreateFormFile("attachment", filepath.Base(uploadPath)) + if err != nil { + fmt.Printf("Failed to create form: %v\n", err) + continue + } + + src, err := os.Open(uploadPath) + if err != nil { + fmt.Printf("Cannot open file %s: %v\n", file.Name(), err) + continue + } + io.Copy(part, src) + src.Close() + writer.Close() + + req, err := http.NewRequest("POST", uploadURL+"/assets", buf) + if err != nil { + fmt.Printf("NewRequest error: %v\n", err) + continue + } + req.Header.Set("Authorization", "token "+token) + req.Header.Set("Content-Type", writer.FormDataContentType()) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + fmt.Printf("Upload failed: %v\n", err) + continue + } + if resp.StatusCode != http.StatusCreated { + bodyBytes, _ := io.ReadAll(resp.Body) + fmt.Printf("Upload failed: %s\n", bodyBytes) + } else { + fmt.Println("Uploaded:", file.Name()) + } + resp.Body.Close() + } +} diff --git a/script/release.json b/script/release.json new file mode 100644 index 0000000..00b55e8 --- /dev/null +++ b/script/release.json @@ -0,0 +1,5 @@ +{ + "tag": "3.6.2-01", + "title": "PreBuild Version 3.6.52 - 01" +} + \ No newline at end of file