diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml
new file mode 100644
index 0000000000000000000000000000000000000000..5e26bf89e907450774ef78d1632fa5981fdd8399
--- /dev/null
+++ b/.github/workflows/update.yml
@@ -0,0 +1,75 @@
+name: Update Components
+
+on:
+  schedule:
+    - cron: "*/10 * * * *"
+
+jobs:
+  update-components:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Check out code
+        uses: actions/checkout@v2
+
+      - name: Update component versions
+        id: update
+        run: |
+          PR_BODY=""
+
+          bump_version() {
+            local RELEASE_VERSION=$(curl -s https://api.github.com/repos/fluxcd/$1/releases | jq -r 'sort_by(.published_at) | .[-1] | .tag_name')
+            local CURRENT_VERSION=$(go list -m all | grep "github.com/fluxcd/$1/api" | awk '{print $2}')
+
+            if [[ "${RELEASE_VERSION}" != "${CURRENT_VERSION}" ]]; then
+              # bump go mod
+              go mod edit -require="github.com/fluxcd/$1/api@${RELEASE_VERSION}"
+
+              # bump kustomize
+              sed -i "s/\($1\/.*?ref=\).*/\1${RELEASE_VERSION}/g" "manifests/bases/$1/kustomization.yaml"
+
+              # bump doc var
+              if [[ $2 ]]; then
+                sed -i "s/\($2:\s*.{{\s*'\)\(v[0-9.]\+\)\('\s*}}\)/\1${RELEASE_VERSION}\3/" .github/workflows/docs.yaml
+              fi
+
+              PR_BODY="$PR_BODY- $1 to ${RELEASE_VERSION}%0A"
+            fi
+          }
+
+          {
+            # bump controller versions
+            bump_version helm-controller HELM_VER
+            bump_version kustomize-controller KUSTOMIZE_VER
+            bump_version source-controller SOURCE_VER
+
+            # add missing and remove unused modules
+            go mod tidy
+
+            # diff change
+            git diff
+
+            # export PR_BODY for PR
+            echo "::set-output name=pr_body::$PR_BODY"
+          }
+
+      - name: Create Pull Request
+        id: cpr
+        uses: peter-evans/create-pull-request@v3
+        with:
+            token: ${{ secrets.GITHUB_TOKEN }}
+            commit-message: Update toolkit components
+            committer: GitHub <noreply@github.com>
+            author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
+            title: Update toolkit components
+            body: |
+              ${{ steps.update.outputs.pr_body }}
+
+              Auto-generated by [create-pull-request][1]
+
+              [1]: https://github.com/peter-evans/create-pull-request
+            branch: update-components
+            reviewers: ${{ secrets.ASSIGNEES }}
+
+      - name: Check output
+        run: |
+          echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"