diff --git a/joint_teapot/app.py b/joint_teapot/app.py
index ab70c74..230f79f 100644
--- a/joint_teapot/app.py
+++ b/joint_teapot/app.py
@@ -90,8 +90,16 @@ def create_issue_for_repos(
     use_regex: bool = Option(
         False, "--regex", help="repo_names takes list of regexes if set"
     ),
+    milesetone: str = Option("", "--milestone", help="milestone title"),
+    labels: List[str] = Option(
+        [],
+        "--label",
+        help="labels to add to the issue (use --label A --label B to add multiple)",
+    ),
 ) -> None:
-    tea.pot.create_issue_for_repos(repo_names, title, body, from_file, use_regex)
+    tea.pot.create_issue_for_repos(
+        repo_names, title, body, from_file, use_regex, milesetone, labels
+    )
 
 
 @app.command("create-comment", help="create a comment for an issue on gitea")
@@ -103,11 +111,17 @@ def create_comment(
     tea.pot.create_comment(repo_name, index, body)
 
 
-@app.command("create-milestones", help="create milestones on gitea")
-def create_milestone_for_repos(
-    repo_names: List[str], title: str, description: str, due_on: datetime
+@app.command(
+    "create-milestones",
+    help="create milestones on gitea",
+)
+def create_milestones(
+    title: str,
+    regex: str = Argument(".+"),
+    due_on: str = Argument("", help="milestone due-on date [%YYYY-%MM-%DD]"),
+    description: str = Argument(""),
 ) -> None:
-    tea.pot.create_milestone_for_repos(repo_names, title, description, due_on)
+    tea.pot.gitea.create_milestones(title, regex, due_on, description)
 
 
 @app.command("check-issues", help="check the existence of issue by title on gitea")
diff --git a/joint_teapot/teapot.py b/joint_teapot/teapot.py
index 129b08c..5efad94 100644
--- a/joint_teapot/teapot.py
+++ b/joint_teapot/teapot.py
@@ -146,6 +146,8 @@ class Teapot:
         body: str,
         from_file: bool = False,
         use_regex: bool = False,
+        milestone: str = "",
+        labels: List[str] = [],
     ) -> None:
         if from_file:
             try:
@@ -173,7 +175,7 @@ class Teapot:
             affected_repos = repo_names
 
         for repo_name in affected_repos:
-            self.gitea.create_issue(repo_name, title, content)
+            self.gitea.create_issue(repo_name, title, content, True, milestone, labels)
 
     def create_comment(
         self,
@@ -183,12 +185,6 @@ class Teapot:
     ) -> None:
         self.gitea.create_comment(repo_name, index, body)
 
-    def create_milestone_for_repos(
-        self, repo_names: List[str], title: str, description: str, due_on: datetime
-    ) -> None:
-        for repo_name in repo_names:
-            self.gitea.create_milestone(repo_name, title, description, due_on)
-
     def check_exist_issue_by_title(
         self, repo_names: List[str], title: str
     ) -> List[str]:
diff --git a/joint_teapot/workers/gitea.py b/joint_teapot/workers/gitea.py
index 0667ca8..2732662 100644
--- a/joint_teapot/workers/gitea.py
+++ b/joint_teapot/workers/gitea.py
@@ -1,5 +1,4 @@
 import re
-from datetime import datetime
 from enum import Enum
 from functools import lru_cache
 from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, TypeVar
@@ -345,6 +344,8 @@ class Gitea:
         title: str,
         body: str,
         assign_every_collaborators: bool = True,
+        milestone: str = "",
+        labels: list[str] = [],
     ) -> None:
         assignees = []
         if assign_every_collaborators:
@@ -356,10 +357,33 @@ class Gitea:
                     repo_name,
                 )
             ]
+        milestone_id = None
+        if milestone:
+            milestone_list = self.issue_api.issue_get_milestones_list(
+                self.org_name, repo_name
+            )
+            if milestone not in [m.title for m in milestone_list]:
+                logger.warning(f"Milestone {milestone} does not exist in {repo_name}")
+            else:
+                milestone_id = first(
+                    [m.id for m in milestone_list if m.title == milestone]
+                )
+        labels_id = []
+        if labels:
+            labels_list = self.issue_api.issue_list_labels(self.org_name, repo_name)
+            labels_id = [l.id for l in labels_list if l.name in labels]
+            if not labels_id:
+                logger.warning(f"no label matches {labels}")
         self.issue_api.issue_create_issue(
             self.org_name,
             repo_name,
-            body={"title": title, "body": body, "assignees": assignees},
+            body={
+                "title": title,
+                "body": body,
+                "assignees": assignees,
+                "milestone": milestone_id,
+                "labels": labels_id,
+            },
         )
         logger.info(f'Created issue "{title}" in {repo_name}')
 
@@ -382,15 +406,22 @@ class Gitea:
         repo_name: str,
         title: str,
         description: str,
-        due_on: datetime,
+        due_on: str,
     ) -> None:
+        if due_on == "":
+            self.issue_api.issue_create_milestone(
+                self.org_name,
+                repo_name,
+                body={"title": title, "description": description},
+            )
+            return
         self.issue_api.issue_create_milestone(
             self.org_name,
             repo_name,
             body={
                 "title": title,
                 "description": description,
-                "due_on": due_on.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
+                "due_on": due_on + "T23:59:59.999Z",
             },
         )
 
@@ -469,6 +500,21 @@ class Gitea:
             )
             logger.info(f"Unsubscribed from {sub.name}")
 
+    def create_milestones(
+        self, milestone: str, regex: str, due_date: str, description: str
+    ) -> None:
+        for repo_name in self.get_all_repo_names():
+            if not re.match(regex, repo_name):
+                continue
+            milestone_list = self.issue_api.issue_get_milestones_list(
+                self.org_name, repo_name
+            )
+            if milestone in [m.title for m in milestone_list]:
+                logger.warning(f"Milestone {milestone} already exists in {repo_name}")
+                continue
+            self.create_milestone(repo_name, milestone, description, due_date)
+            logger.info(f"Created milestone {milestone} in {repo_name}")
+
 
 if __name__ == "__main__":
     gitea = Gitea()