Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
url = https://github.com/ActivityWatch/aw-client.git
[submodule "aw-server"]
path = aw-server
url = https://github.com/ActivityWatch/aw-server.git
url = git@github.com:odoo/aw-server.git
[submodule "aw-watcher-afk"]
Comment on lines +9 to 10
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0 Submodule URLs point to Odoo SSH forks instead of upstream ActivityWatch repos

Both aw-server and aw-server-rust submodule URLs have been changed from the official ActivityWatch HTTPS URLs to SSH-based Odoo org forks:

url = git@github.com:odoo/aw-server.git
url = git@github.com:odoo/aw-server-rust.git

This has two significant problems:

  1. SSH vs HTTPS protocol: The upstream repo used HTTPS URLs, which work for anyone. SSH URLs require a properly configured SSH key with access to GitHub. Any contributor cloning this repo without GitHub SSH credentials configured will fail on git submodule update --init.

  2. Odoo-specific forks in the public repo: These point to odoo/aw-server and odoo/aw-server-rust, which are Odoo internal forks. If those repos are private, every contributor to the ActivityWatch project will be unable to fetch the submodules. Even if they are public, they replace the canonical ActivityWatch source, which is unexpected for a community project.

The same issue appears at line 19 for aw-server-rust.

These should either revert to the upstream ActivityWatch HTTPS URLs, or the Odoo-specific overrides should be kept out-of-tree (e.g., via a local .gitconfig override or a separate odoo-specific manifest).

path = aw-watcher-afk
url = https://github.com/ActivityWatch/aw-watcher-afk.git
Expand All @@ -18,7 +18,7 @@
url = https://github.com/ActivityWatch/aw-watcher-window.git
[submodule "aw-server-rust"]
path = aw-server-rust
url = https://github.com/ActivityWatch/aw-server-rust.git
url = git@github.com:odoo/aw-server-rust.git
[submodule "aw-watcher-input"]
path = aw-watcher-input
url = https://github.com/ActivityWatch/aw-watcher-input.git
Expand Down
22 changes: 18 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ endif
ifeq ($(SKIP_SERVER_RUST),true)
SUBMODULES := $(filter-out aw-server-rust,$(SUBMODULES))
endif
# Exclude aw-server (Python) when using aw-server-rust only
ifeq ($(SKIP_SERVER_PYTHON),true)
SUBMODULES := $(filter-out aw-server,$(SUBMODULES))
endif
# Odoo-specific Windows build: replaces aw-qt with aw-systray-odoo
ifeq ($(ODOO_WINDOWS_BUILD),true)
SUBMODULES := $(filter-out aw-qt,$(SUBMODULES))
endif
# Include extras if AW_EXTRAS is true
Comment on lines +32 to 38
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Inconsistent indentation in new ifeq blocks (spaces vs tabs)

The existing ifeq blocks in this Makefile use tab indentation for commands inside them, but the two new blocks use 4-space indentation. Please align with the file's existing style.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

ifeq ($(AW_EXTRAS),true)
SUBMODULES := $(SUBMODULES) aw-notify aw-watcher-input
Expand Down Expand Up @@ -79,7 +87,9 @@ build: aw-core/.git
make --directory=aw-client build
make --directory=aw-core build
# Needed to ensure that the server has the correct version set
ifneq ($(SKIP_SERVER_PYTHON),true)
python -c "import aw_server; print(aw_server.__version__)"
endif


# Install
Expand Down Expand Up @@ -194,10 +204,14 @@ ifeq ($(TAURI_BUILD),true)
mkdir -p dist/activitywatch/aw-server-rust
cp aw-server-rust/target/$(targetdir)/aw-sync dist/activitywatch/aw-server-rust/aw-sync
else
# Move aw-qt to the root of the dist folder
mv dist/activitywatch/aw-qt aw-qt-tmp
mv aw-qt-tmp/* dist/activitywatch
rmdir aw-qt-tmp
ifeq ($(ODOO_WINDOWS_BUILD),true)
# ODOO_WINDOWS_BUILD: Install pystray and build aw-systray-odoo.exe via PyInstaller
@echo "ODOO_WINDOWS_BUILD: Installing pystray..."
python -m pip install pystray pillow pywin32
@echo "ODOO_WINDOWS_BUILD: Building aw-systray-odoo.exe via PyInstaller..."
pyinstaller --clean --noconfirm odoo-setup/aw-systray-odoo.spec
cp dist/aw-systray-odoo.exe dist/activitywatch/aw-systray-odoo.exe
endif
endif
# Remove problem-causing binaries
rm -f dist/activitywatch/libdrm.so.2 # see: https://github.com/ActivityWatch/activitywatch/issues/161
Expand Down
2 changes: 1 addition & 1 deletion aw-server
53 changes: 34 additions & 19 deletions aw.spec
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,25 @@ if not aw_server_rust_bin.exists():
skip_rust = True
print("Skipping Rust build because aw-server-rust binary not found.")

skip_aw_server_python = os.environ.get("SKIP_SERVER_PYTHON", "false").lower() == "true"
if skip_aw_server_python:
print("Skipping aw-server (Python) packaging, using aw-server-rust only.")

aw_qt_a = build_analysis(
"aw-qt",
aw_qt_location,
binaries=[(aw_server_rust_bin, "."), (aw_sync_bin, ".")] if not skip_rust else [],
datas=[
(aw_qt_location / "resources/aw-qt.desktop", "aw_qt/resources"),
(aw_qt_location / "media", "aw_qt/media"),
],
)
skip_aw_qt = os.environ.get("ODOO_WINDOWS_BUILD", "false").lower() == "true"
if skip_aw_qt:
print("Skipping aw-qt packaging, using aw-systray-odoo instead.")


if not skip_aw_qt:
aw_qt_a = build_analysis(
"aw-qt",
aw_qt_location,
binaries=[(aw_server_rust_bin, "."), (aw_sync_bin, ".")] if not skip_rust else [],
datas=[
(aw_qt_location / "resources/aw-qt.desktop", "aw_qt/resources"),
(aw_qt_location / "media", "aw_qt/media"),
],
)
aw_server_a = build_analysis(
Comment on lines +121 to 123
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 aw_server_a analysis is always built even when skip_aw_server_python=True

When SKIP_SERVER_PYTHON=true, the script sets skip_aw_server_python = True and skips creating aws_coll, but the aw_server_a analysis on line 121 is still unconditionally executed:

aw_server_a = build_analysis(
    "aw-server",
    aws_location,
    ...
)

This means PyInstaller still performs the full dependency analysis of the Python server even in the SKIP_SERVER_PYTHON=true case, which defeats the purpose of the flag. If the aw-server Python source is not present (e.g., when building without that submodule), this will also fail with a FileNotFoundError.

The build_analysis call should also be guarded:

if not skip_aw_server_python:
    aw_server_a = build_analysis(
        "aw-server",
        aws_location,
        ...
    )

"aw-server",
aws_location,
Expand Down Expand Up @@ -182,20 +191,23 @@ aw_notify_a = None if skip_aw_notify else build_analysis(
# MERGE takes a bit weird arguments, it wants tuples which consists of
# the analysis paired with the script name and the bin name
merge_args = [
(aw_server_a, "aw-server", "aw-server"),
(aw_qt_a, "aw-qt", "aw-qt"),
(aw_watcher_afk_a, "aw-watcher-afk", "aw-watcher-afk"),
(aw_watcher_window_a, "aw-watcher-window", "aw-watcher-window"),
(aw_watcher_input_a, "aw-watcher-input", "aw-watcher-input"),
]
if not skip_aw_server_python:
merge_args.insert(0, (aw_server_a, "aw-server", "aw-server"))
if not skip_aw_qt:
merge_args.append((aw_qt_a, "aw-qt", "aw-qt"))
if aw_notify_a is not None:
merge_args.append((aw_notify_a, "aw-notify", "aw-notify"))

MERGE(*merge_args)


# aw-server
aws_coll = build_collect(aw_server_a, "aw-server")
if not skip_aw_server_python:
aws_coll = build_collect(aw_server_a, "aw-server")

# aw-watcher-window
aww_coll = build_collect(aw_watcher_window_a, "aw-watcher-window")
Expand All @@ -204,11 +216,12 @@ aww_coll = build_collect(aw_watcher_window_a, "aw-watcher-window")
awa_coll = build_collect(aw_watcher_afk_a, "aw-watcher-afk")

# aw-qt
awq_coll = build_collect(
aw_qt_a,
"aw-qt",
console=False if platform.system() == "Windows" else True,
)
if not skip_aw_qt:
awq_coll = build_collect(
aw_qt_a,
"aw-qt",
console=False if platform.system() == "Windows" else True,
)

# aw-watcher-input
awi_coll = build_collect(aw_watcher_input_a, "aw-watcher-input")
Expand All @@ -218,12 +231,14 @@ aw_notify_coll = build_collect(aw_notify_a, "aw-notify") if aw_notify_a is not N

if platform.system() == "Darwin":
bundle_args = [
awq_coll,
aws_coll,
aww_coll,
awa_coll,
awi_coll,
]
if not skip_aw_server_python:
bundle_args.insert(1, aws_coll)
if not skip_aw_qt:
bundle_args.insert(0, awq_coll)
if aw_notify_coll is not None:
bundle_args.append(aw_notify_coll)

Expand Down
38 changes: 38 additions & 0 deletions odoo-setup/Dockerfile_jammy
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
FROM ubuntu:jammy

ENV DEBIAN_FRONTEND=noninteractive
ARG USID=1000 GRID=1000

RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates apt-transport-https adduser \
build-essential zip unzip git curl \
python3 python3-dev python3-pip python3-venv curl \
pkgconf libssl-dev libxkbcommon-dev libglib2.0-0 && \
Comment on lines +9 to +10
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Duplicate curl package in apt-get install

curl appears twice in the same apt-get install command:

apt-get install -y --no-install-recommends ca-certificates apt-transport-https adduser \
        build-essential zip unzip git curl \
        python3 python3-dev python3-pip python3-venv curl \

While this doesn't cause a build failure, it's a leftover from copy-paste and should be cleaned up.

rm -rf /var/lib/apt/lists/*

RUN groupadd -g $GRID odoo && useradd --create-home -u $USID -g odoo -G audio,video odoo

RUN mkdir -p /data/build && chown -R odoo:odoo /data/build

USER odoo

RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/home/odoo/.cargo/bin:${PATH}"

ENV NVM_DIR=/home/odoo/.nvm
ENV NODE_VERSION=22.22.1
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash && \
bash -c "source $NVM_DIR/nvm.sh && \
nvm install $NODE_VERSION && \
nvm alias default $NODE_VERSION && \
nvm use default"

ENV PATH="$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH"

RUN rustup toolchain install nightly && \
rustup default nightly

RUN python3 -m venv /data/build/awvenv
ENV PATH="/data/build/awvenv/bin:$PATH"
ENV VIRTUAL_ENV=/data/build/awvenv
RUN python3 -m pip install poetry==1.8.2
35 changes: 35 additions & 0 deletions odoo-setup/Dockerfile_noble
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
FROM ubuntu:noble

ENV DEBIAN_FRONTEND=noninteractive
ARG USID=1000 GRID=1000

RUN apt-get update && \
apt-get install -y --no-install-recommends ca-certificates apt-transport-https adduser \
build-essential zip unzip git curl rustup \
python3 python3-dev python3-pip python3-venv python3-poetry curl rustup \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Duplicate curl and rustup packages in apt-get install

Both curl and rustup appear twice in the same apt-get install line. Additionally, Dockerfile_noble installs python3-poetry via apt-get but the venv is created manually without using it, while Dockerfile_jammy installs poetry via pip. Consider making them consistent.

pkgconf libssl-dev libxkbcommon-dev libglib2.0-0t64 && \
rm -rf /var/lib/apt/lists/*

RUN deluser --remove-home ubuntu && \
groupadd -g $GRID odoo && useradd --create-home -u $USID -g odoo -G audio,video odoo

RUN mkdir -p /data/build && chown -R odoo:odoo /data/build

USER odoo

ENV NVM_DIR=/home/odoo/.nvm
ENV NODE_VERSION=22.22.1
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash && \
bash -c "source $NVM_DIR/nvm.sh && \
nvm install $NODE_VERSION && \
nvm alias default $NODE_VERSION && \
nvm use default"

ENV PATH="$NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH"

RUN rustup toolchain install nightly && \
rustup default nightly

RUN python3 -m venv /data/build/awvenv
ENV PATH="/data/build/awvenv/bin:$PATH"
ENV VIRTUAL_ENV=/data/build/awvenv
13 changes: 13 additions & 0 deletions odoo-setup/activitywatch-odoo.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[Desktop Entry]
Name=ActivityWatchOdoo
GenericName=Time-tracking application (Odoo Version)
Comment=Open source time-tracking application with a focus on extensibility and privacy.
Exec=/usr/bin/python3 /opt/activitywatch/aw-systray-odoo.py
Hidden=false
StartupNotify=true
Terminal=false
Type=Application
X-GNOME-Autostart-enabled=true
Version=1.0
Icon=activitywatch
Categories=Utility;
Loading